15c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/*
25c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2012 Google Inc. All rights reserved.
35c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
45c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Redistribution and use in source and binary forms, with or without
55c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * modification, are permitted provided that the following conditions
65c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * are met:
75c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
85c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 1.  Redistributions of source code must retain the above copyright
95c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *     notice, this list of conditions and the following disclaimer.
105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 2.  Redistributions in binary form must reproduce the above copyright
115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *     notice, this list of conditions and the following disclaimer in the
125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *     documentation and/or other materials provided with the distribution.
135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */
255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "config.h"
27a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)#include "platform/graphics/DeferredImageDecoder.h"
285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
29c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)#include "SkBitmapDevice.h"
305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "SkCanvas.h"
315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "SkPicture.h"
32f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu#include "SkPictureRecorder.h"
33f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)#include "platform/SharedBuffer.h"
34f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)#include "platform/Task.h"
35a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)#include "platform/graphics/ImageDecodingStore.h"
36a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)#include "platform/graphics/skia/NativeImageSkia.h"
3709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)#include "platform/graphics/test/MockImageDecoder.h"
38f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)#include "public/platform/Platform.h"
39f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)#include "public/platform/WebThread.h"
40521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)#include "wtf/PassRefPtr.h"
41521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)#include "wtf/RefPtr.h"
42521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)#include <gtest/gtest.h>
435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
44bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)namespace WebCore {
455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)namespace {
475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
48926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// Raw data for a PNG file with 1x1 white pixels.
49926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)const unsigned char whitePNG[] = {
50926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00,
51926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x01,
52926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    0x00, 0x00, 0x00, 0x01, 0x08, 0x02, 0x00, 0x00, 0x00, 0x90,
53926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    0x77, 0x53, 0xde, 0x00, 0x00, 0x00, 0x01, 0x73, 0x52, 0x47,
54926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    0x42, 0x00, 0xae, 0xce, 0x1c, 0xe9, 0x00, 0x00, 0x00, 0x09,
55926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x0b, 0x13, 0x00, 0x00,
56926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    0x0b, 0x13, 0x01, 0x00, 0x9a, 0x9c, 0x18, 0x00, 0x00, 0x00,
57926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    0x0c, 0x49, 0x44, 0x41, 0x54, 0x08, 0xd7, 0x63, 0xf8, 0xff,
58926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    0xff, 0x3f, 0x00, 0x05, 0xfe, 0x02, 0xfe, 0xdc, 0xcc, 0x59,
59926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    0xe7, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae,
60926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    0x42, 0x60, 0x82,
61926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)};
62926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
63926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)struct Rasterizer {
64926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    SkCanvas* canvas;
65926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    SkPicture* picture;
66926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)};
67926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
68bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)} // namespace
69bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)
70926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)class DeferredImageDecoderTest : public ::testing::Test, public MockImageDecoderClient {
715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)public:
7206f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    virtual void SetUp() OVERRIDE
735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    {
74d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)        ImageDecodingStore::instance()->setCacheLimitInBytes(1024 * 1024);
75926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        DeferredImageDecoder::setEnabled(true);
76926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        m_data = SharedBuffer::create(whitePNG, sizeof(whitePNG));
77926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        OwnPtr<MockImageDecoder> decoder = MockImageDecoder::create(this);
78926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        m_actualDecoder = decoder.get();
79926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        m_actualDecoder->setSize(1, 1);
80926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        m_lazyDecoder = DeferredImageDecoder::createForTesting(decoder.release());
8143e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles)        m_canvas.reset(SkCanvas::NewRasterN32(100, 100));
8243e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles)        ASSERT_TRUE(m_canvas);
83926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        m_frameBufferRequestCount = 0;
847757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        m_frameCount = 1;
857757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        m_repetitionCount = cAnimationNone;
86c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)        m_status = ImageFrame::FrameComplete;
877757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        m_frameDuration = 0;
8806f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)        m_decodedSize = m_actualDecoder->size();
895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
9106f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    virtual void TearDown() OVERRIDE
925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    {
93d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)        ImageDecodingStore::instance()->clear();
945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
9606f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    virtual void decoderBeingDestroyed() OVERRIDE
97926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    {
98926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        m_actualDecoder = 0;
99926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    }
100926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
10106f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    virtual void frameBufferRequested() OVERRIDE
102926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    {
103926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        ++m_frameBufferRequestCount;
104926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    }
105926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
10606f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    virtual size_t frameCount() OVERRIDE
1077757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    {
1087757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        return m_frameCount;
1097757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    }
1107757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch
11106f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    virtual int repetitionCount() const OVERRIDE
1127757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    {
1137757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        return m_repetitionCount;
1147757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    }
1157757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch
11606f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    virtual ImageFrame::Status status() OVERRIDE
117926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    {
118c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)        return m_status;
1197757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    }
1207757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch
12106f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    virtual float frameDuration() const OVERRIDE
1227757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    {
1237757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        return m_frameDuration;
124926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    }
125926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
12606f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    virtual IntSize decodedSize() const OVERRIDE
12706f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    {
12806f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)        return m_decodedSize;
12906f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    }
13006f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)
1315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)protected:
132bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)    void useMockImageDecoderFactory()
133bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)    {
134bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)        m_lazyDecoder->frameGenerator()->setImageDecoderFactory(MockImageDecoderFactory::create(this, m_decodedSize));
135bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)    }
13606f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)
1375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Don't own this but saves the pointer to query states.
1385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    MockImageDecoder* m_actualDecoder;
1395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    OwnPtr<DeferredImageDecoder> m_lazyDecoder;
140926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    SkAutoTUnref<SkCanvas> m_canvas;
141926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    int m_frameBufferRequestCount;
142926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    RefPtr<SharedBuffer> m_data;
1437757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    size_t m_frameCount;
1447757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    int m_repetitionCount;
145c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)    ImageFrame::Status m_status;
1467757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    float m_frameDuration;
14706f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    IntSize m_decodedSize;
1485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)};
1495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)TEST_F(DeferredImageDecoderTest, drawIntoSkPicture)
1515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
15210f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch    m_lazyDecoder->setData(*m_data, true);
15353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    RefPtr<NativeImageSkia> image = m_lazyDecoder->frameBufferAtIndex(0)->asNewNativeImage();
154926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    EXPECT_EQ(1, image->bitmap().width());
155926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    EXPECT_EQ(1, image->bitmap().height());
1565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    EXPECT_FALSE(image->bitmap().isNull());
1575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    EXPECT_TRUE(image->bitmap().isImmutable());
1585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
15910f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch    SkPictureRecorder recorder;
160f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu    SkCanvas* tempCanvas = recorder.beginRecording(100, 100, 0, 0);
1615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    tempCanvas->drawBitmap(image->bitmap(), 0, 0);
16210f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch    RefPtr<SkPicture> picture = adoptRef(recorder.endRecording());
163926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    EXPECT_EQ(0, m_frameBufferRequestCount);
164926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
165f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    m_canvas->drawPicture(picture.get());
166926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    EXPECT_EQ(0, m_frameBufferRequestCount);
1675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
168926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    SkBitmap canvasBitmap;
16943e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles)    ASSERT_TRUE(canvasBitmap.allocN32Pixels(100, 100));
170926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    ASSERT_TRUE(m_canvas->readPixels(&canvasBitmap, 0, 0));
171926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    SkAutoLockPixels autoLock(canvasBitmap);
172926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    EXPECT_EQ(SkColorSetARGB(255, 255, 255, 255), canvasBitmap.getColor(0, 0));
1735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
175d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)TEST_F(DeferredImageDecoderTest, drawIntoSkPictureProgressive)
176d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles){
177d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    RefPtr<SharedBuffer> partialData = SharedBuffer::create(m_data->data(), m_data->size() - 10);
178d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
179d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    // Received only half the file.
18010f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch    m_lazyDecoder->setData(*partialData, false);
181d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    RefPtr<NativeImageSkia> image = m_lazyDecoder->frameBufferAtIndex(0)->asNewNativeImage();
18210f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch    SkPictureRecorder recorder;
183f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu    SkCanvas* tempCanvas = recorder.beginRecording(100, 100, 0, 0);
184d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    tempCanvas->drawBitmap(image->bitmap(), 0, 0);
18510f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch    RefPtr<SkPicture> picture = adoptRef(recorder.endRecording());
186f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    m_canvas->drawPicture(picture.get());
187d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
188d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    // Fully received the file and draw the SkPicture again.
18910f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch    m_lazyDecoder->setData(*m_data, true);
190d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    image = m_lazyDecoder->frameBufferAtIndex(0)->asNewNativeImage();
191f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu    tempCanvas = recorder.beginRecording(100, 100, 0, 0);
192d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    tempCanvas->drawBitmap(image->bitmap(), 0, 0);
19310f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch    picture = adoptRef(recorder.endRecording());
194f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    m_canvas->drawPicture(picture.get());
195d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
196d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    SkBitmap canvasBitmap;
19743e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles)    ASSERT_TRUE(canvasBitmap.allocN32Pixels(100, 100));
198d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    ASSERT_TRUE(m_canvas->readPixels(&canvasBitmap, 0, 0));
199d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    SkAutoLockPixels autoLock(canvasBitmap);
200d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    EXPECT_EQ(SkColorSetARGB(255, 255, 255, 255), canvasBitmap.getColor(0, 0));
201d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)}
202d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
203f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)static void rasterizeMain(SkCanvas* canvas, SkPicture* picture)
204926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){
205f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    canvas->drawPicture(picture);
206926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)}
207926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
208926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)TEST_F(DeferredImageDecoderTest, decodeOnOtherThread)
209926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){
21010f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch    m_lazyDecoder->setData(*m_data, true);
21153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    RefPtr<NativeImageSkia> image = m_lazyDecoder->frameBufferAtIndex(0)->asNewNativeImage();
212926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    EXPECT_EQ(1, image->bitmap().width());
213926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    EXPECT_EQ(1, image->bitmap().height());
214926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    EXPECT_FALSE(image->bitmap().isNull());
215926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    EXPECT_TRUE(image->bitmap().isImmutable());
216926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
21710f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch    SkPictureRecorder recorder;
218f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu    SkCanvas* tempCanvas = recorder.beginRecording(100, 100, 0, 0);
219926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    tempCanvas->drawBitmap(image->bitmap(), 0, 0);
22010f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch    RefPtr<SkPicture> picture = adoptRef(recorder.endRecording());
221926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    EXPECT_EQ(0, m_frameBufferRequestCount);
222926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
223926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    // Create a thread to rasterize SkPicture.
22451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    OwnPtr<blink::WebThread> thread = adoptPtr(blink::Platform::current()->createThread("RasterThread"));
22510f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch    thread->postTask(new Task(WTF::bind(&rasterizeMain, m_canvas.get(), picture.get())));
226f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)    thread.clear();
227926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    EXPECT_EQ(0, m_frameBufferRequestCount);
2285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
229926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    SkBitmap canvasBitmap;
23043e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles)    ASSERT_TRUE(canvasBitmap.allocN32Pixels(100, 100));
231926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    ASSERT_TRUE(m_canvas->readPixels(&canvasBitmap, 0, 0));
232926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    SkAutoLockPixels autoLock(canvasBitmap);
233926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    EXPECT_EQ(SkColorSetARGB(255, 255, 255, 255), canvasBitmap.getColor(0, 0));
2345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2367757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen MurdochTEST_F(DeferredImageDecoderTest, singleFrameImageLoading)
2377757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch{
238c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)    m_status = ImageFrame::FramePartial;
23910f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch    m_lazyDecoder->setData(*m_data, false);
2407757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    EXPECT_FALSE(m_lazyDecoder->frameIsCompleteAtIndex(0));
2417757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    ImageFrame* frame = m_lazyDecoder->frameBufferAtIndex(0);
24209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    unsigned firstId = frame->getSkBitmap().getGenerationID();
2437757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    EXPECT_EQ(ImageFrame::FramePartial, frame->status());
2447757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    EXPECT_TRUE(m_actualDecoder);
2457757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch
246c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)    m_status = ImageFrame::FrameComplete;
24709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    m_data->append(" ", 1);
24810f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch    m_lazyDecoder->setData(*m_data, true);
2497757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    EXPECT_FALSE(m_actualDecoder);
2507757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    EXPECT_TRUE(m_lazyDecoder->frameIsCompleteAtIndex(0));
2517757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    frame = m_lazyDecoder->frameBufferAtIndex(0);
25209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    unsigned secondId = frame->getSkBitmap().getGenerationID();
2537757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    EXPECT_EQ(ImageFrame::FrameComplete, frame->status());
2547757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    EXPECT_FALSE(m_frameBufferRequestCount);
25509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    EXPECT_NE(firstId, secondId);
25609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
25709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    EXPECT_EQ(secondId, m_lazyDecoder->frameBufferAtIndex(0)->getSkBitmap().getGenerationID());
2587757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch}
2597757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch
2607757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen MurdochTEST_F(DeferredImageDecoderTest, multiFrameImageLoading)
2617757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch{
2627757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    m_repetitionCount = 10;
2637757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    m_frameCount = 1;
2647757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    m_frameDuration = 10;
265c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)    m_status = ImageFrame::FramePartial;
26610f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch    m_lazyDecoder->setData(*m_data, false);
2677757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    EXPECT_EQ(ImageFrame::FramePartial, m_lazyDecoder->frameBufferAtIndex(0)->status());
26809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    unsigned firstId = m_lazyDecoder->frameBufferAtIndex(0)->getSkBitmap().getGenerationID();
2697757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    EXPECT_FALSE(m_lazyDecoder->frameIsCompleteAtIndex(0));
2707757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    EXPECT_EQ(10.0f, m_lazyDecoder->frameBufferAtIndex(0)->duration());
2717757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    EXPECT_EQ(10.0f, m_lazyDecoder->frameDurationAtIndex(0));
2727757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch
2737757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    m_frameCount = 2;
2747757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    m_frameDuration = 20;
275c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)    m_status = ImageFrame::FrameComplete;
27609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    m_data->append(" ", 1);
27710f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch    m_lazyDecoder->setData(*m_data, false);
2787757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    EXPECT_EQ(ImageFrame::FrameComplete, m_lazyDecoder->frameBufferAtIndex(0)->status());
2797757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    EXPECT_EQ(ImageFrame::FrameComplete, m_lazyDecoder->frameBufferAtIndex(1)->status());
28009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    unsigned secondId = m_lazyDecoder->frameBufferAtIndex(0)->getSkBitmap().getGenerationID();
28109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    EXPECT_NE(firstId, secondId);
2827757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    EXPECT_TRUE(m_lazyDecoder->frameIsCompleteAtIndex(0));
2837757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    EXPECT_TRUE(m_lazyDecoder->frameIsCompleteAtIndex(1));
2847757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    EXPECT_EQ(20.0f, m_lazyDecoder->frameDurationAtIndex(1));
2857757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    EXPECT_EQ(10.0f, m_lazyDecoder->frameBufferAtIndex(0)->duration());
2867757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    EXPECT_EQ(20.0f, m_lazyDecoder->frameBufferAtIndex(1)->duration());
2877757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    EXPECT_TRUE(m_actualDecoder);
2887757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch
2897757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    m_frameCount = 3;
2907757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    m_frameDuration = 30;
291c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)    m_status = ImageFrame::FrameComplete;
29210f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch    m_lazyDecoder->setData(*m_data, true);
2937757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    EXPECT_FALSE(m_actualDecoder);
2947757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    EXPECT_EQ(ImageFrame::FrameComplete, m_lazyDecoder->frameBufferAtIndex(0)->status());
2957757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    EXPECT_EQ(ImageFrame::FrameComplete, m_lazyDecoder->frameBufferAtIndex(1)->status());
2967757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    EXPECT_EQ(ImageFrame::FrameComplete, m_lazyDecoder->frameBufferAtIndex(2)->status());
29709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    EXPECT_EQ(secondId, m_lazyDecoder->frameBufferAtIndex(0)->getSkBitmap().getGenerationID());
2987757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    EXPECT_TRUE(m_lazyDecoder->frameIsCompleteAtIndex(0));
2997757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    EXPECT_TRUE(m_lazyDecoder->frameIsCompleteAtIndex(1));
3007757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    EXPECT_TRUE(m_lazyDecoder->frameIsCompleteAtIndex(2));
3017757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    EXPECT_EQ(10.0f, m_lazyDecoder->frameDurationAtIndex(0));
3027757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    EXPECT_EQ(20.0f, m_lazyDecoder->frameDurationAtIndex(1));
3037757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    EXPECT_EQ(30.0f, m_lazyDecoder->frameDurationAtIndex(2));
3047757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    EXPECT_EQ(10.0f, m_lazyDecoder->frameBufferAtIndex(0)->duration());
3057757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    EXPECT_EQ(20.0f, m_lazyDecoder->frameBufferAtIndex(1)->duration());
3067757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    EXPECT_EQ(30.0f, m_lazyDecoder->frameBufferAtIndex(2)->duration());
3077757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    EXPECT_EQ(10, m_lazyDecoder->repetitionCount());
3087757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch}
3097757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch
31006f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)TEST_F(DeferredImageDecoderTest, decodedSize)
31106f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles){
31206f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    m_decodedSize = IntSize(22, 33);
31310f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch    m_lazyDecoder->setData(*m_data, true);
31406f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    RefPtr<NativeImageSkia> image = m_lazyDecoder->frameBufferAtIndex(0)->asNewNativeImage();
31506f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    EXPECT_EQ(m_decodedSize.width(), image->bitmap().width());
31606f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    EXPECT_EQ(m_decodedSize.height(), image->bitmap().height());
31706f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    EXPECT_FALSE(image->bitmap().isNull());
31806f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    EXPECT_TRUE(image->bitmap().isImmutable());
31906f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)
320bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)    useMockImageDecoderFactory();
32106f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)
32206f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    // The following code should not fail any assert.
32310f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch    SkPictureRecorder recorder;
324f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu    SkCanvas* tempCanvas = recorder.beginRecording(100, 100, 0, 0);
32506f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    tempCanvas->drawBitmap(image->bitmap(), 0, 0);
32610f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch    RefPtr<SkPicture> picture = adoptRef(recorder.endRecording());
32706f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    EXPECT_EQ(0, m_frameBufferRequestCount);
328f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    m_canvas->drawPicture(picture.get());
32906f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    EXPECT_EQ(1, m_frameBufferRequestCount);
33006f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)}
33106f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)
33207a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben MurdochTEST_F(DeferredImageDecoderTest, smallerFrameCount)
33307a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch{
33407a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    m_frameCount = 1;
33510f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch    m_lazyDecoder->setData(*m_data, false);
33607a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    EXPECT_EQ(m_frameCount, m_lazyDecoder->frameCount());
33707a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    m_frameCount = 2;
33810f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch    m_lazyDecoder->setData(*m_data, false);
33907a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    EXPECT_EQ(m_frameCount, m_lazyDecoder->frameCount());
34007a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    m_frameCount = 0;
34110f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch    m_lazyDecoder->setData(*m_data, true);
34207a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    EXPECT_EQ(m_frameCount, m_lazyDecoder->frameCount());
34307a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch}
34407a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch
345bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)} // namespace WebCore
346