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