Home | History | Annotate | Download | only in graphics
      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 
     44 namespace WebCore {
     45 
     46 namespace {
     47 
     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,
     60     0x42, 0x60, 0x82,
     61 };
     62 
     63 struct Rasterizer {
     64     SkCanvas* canvas;
     65     SkPicture* picture;
     66 };
     67 
     68 } // namespace
     69 
     70 class DeferredImageDecoderTest : public ::testing::Test, public MockImageDecoderClient {
     71 public:
     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);
     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 
    131 protected:
    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 
    150 TEST_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     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));
    173 }
    174 
    175 TEST_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     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));
    201 }
    202 
    203 static void rasterizeMain(SkCanvas* canvas, SkPicture* picture)
    204 {
    205     canvas->drawPicture(picture);
    206 }
    207 
    208 TEST_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<blink::WebThread> thread = adoptPtr(blink::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     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));
    234 }
    235 
    236 TEST_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 
    260 TEST_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 
    310 TEST_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 
    332 TEST_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 WebCore
    346