| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2012 Google Inc. All rights reserved. | 2 * Copyright (C) 2012 Google Inc. All rights reserved. |
| 3 * | 3 * |
| 4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
| 5 * modification, are permitted provided that the following conditions | 5 * modification, are permitted provided that the following conditions |
| 6 * are met: | 6 * are met: |
| 7 * 1. Redistributions of source code must retain the above copyright | 7 * 1. Redistributions of source code must retain the above copyright |
| 8 * notice, this list of conditions and the following disclaimer. | 8 * notice, this list of conditions and the following disclaimer. |
| 9 * 2. Redistributions in binary form must reproduce the above copyright | 9 * 2. Redistributions in binary form must reproduce the above copyright |
| 10 * notice, this list of conditions and the following disclaimer in the | 10 * notice, this list of conditions and the following disclaimer in the |
| (...skipping 27 matching lines...) Expand all Loading... |
| 38 // URI label for SkDiscardablePixelRef. | 38 // URI label for SkDiscardablePixelRef. |
| 39 const char labelDiscardable[] = "discardable"; | 39 const char labelDiscardable[] = "discardable"; |
| 40 | 40 |
| 41 } // namespace | 41 } // namespace |
| 42 | 42 |
| 43 bool DeferredImageDecoder::s_enabled = false; | 43 bool DeferredImageDecoder::s_enabled = false; |
| 44 | 44 |
| 45 DeferredImageDecoder::DeferredImageDecoder(PassOwnPtr<ImageDecoder> actualDecode
r) | 45 DeferredImageDecoder::DeferredImageDecoder(PassOwnPtr<ImageDecoder> actualDecode
r) |
| 46 : m_allDataReceived(false) | 46 : m_allDataReceived(false) |
| 47 , m_lastDataSize(0) | 47 , m_lastDataSize(0) |
| 48 , m_dataChanged(false) | |
| 49 , m_actualDecoder(actualDecoder) | 48 , m_actualDecoder(actualDecoder) |
| 50 , m_orientation(DefaultImageOrientation) | |
| 51 , m_repetitionCount(cAnimationNone) | 49 , m_repetitionCount(cAnimationNone) |
| 52 , m_hasColorProfile(false) | 50 , m_hasColorProfile(false) |
| 53 { | 51 { |
| 54 } | 52 } |
| 55 | 53 |
| 56 DeferredImageDecoder::~DeferredImageDecoder() | 54 DeferredImageDecoder::~DeferredImageDecoder() |
| 57 { | 55 { |
| 58 } | 56 } |
| 59 | 57 |
| 60 PassOwnPtr<DeferredImageDecoder> DeferredImageDecoder::create(const SharedBuffer
& data, ImageSource::AlphaOption alphaOption, ImageSource::GammaAndColorProfileO
ption gammaAndColorOption) | 58 PassOwnPtr<DeferredImageDecoder> DeferredImageDecoder::create(const SharedBuffer
& data, ImageSource::AlphaOption alphaOption, ImageSource::GammaAndColorProfileO
ption gammaAndColorOption) |
| (...skipping 22 matching lines...) Expand all Loading... |
| 83 bool DeferredImageDecoder::enabled() | 81 bool DeferredImageDecoder::enabled() |
| 84 { | 82 { |
| 85 return s_enabled; | 83 return s_enabled; |
| 86 } | 84 } |
| 87 | 85 |
| 88 String DeferredImageDecoder::filenameExtension() const | 86 String DeferredImageDecoder::filenameExtension() const |
| 89 { | 87 { |
| 90 return m_actualDecoder ? m_actualDecoder->filenameExtension() : m_filenameEx
tension; | 88 return m_actualDecoder ? m_actualDecoder->filenameExtension() : m_filenameEx
tension; |
| 91 } | 89 } |
| 92 | 90 |
| 93 ImageFrame* DeferredImageDecoder::frameBufferAtIndex(size_t index) | 91 PassRefPtr<NativeImageSkia> DeferredImageDecoder::createFrameAtIndex(size_t inde
x) |
| 94 { | 92 { |
| 95 prepareLazyDecodedFrames(); | 93 prepareLazyDecodedFrames(); |
| 96 if (index < m_lazyDecodedFrames.size()) { | 94 if (index < m_frameData.size()) { |
| 97 // ImageFrameGenerator has the latest known alpha state. There will | 95 // ImageFrameGenerator has the latest known alpha state. There will |
| 98 // be a performance boost if this frame is opaque. | 96 // be a performance boost if this frame is opaque. |
| 99 m_lazyDecodedFrames[index]->setHasAlpha(m_frameGenerator->hasAlpha(index
)); | 97 SkBitmap bitmap = createBitmap(index); |
| 100 return m_lazyDecodedFrames[index].get(); | 98 if (m_frameGenerator->hasAlpha(index)) { |
| 99 m_frameData[index].m_hasAlpha = true; |
| 100 bitmap.setAlphaType(kPremul_SkAlphaType); |
| 101 } else { |
| 102 m_frameData[index].m_hasAlpha = false; |
| 103 bitmap.setAlphaType(kOpaque_SkAlphaType); |
| 104 } |
| 105 m_frameData[index].m_frameBytes = m_size.area() * sizeof(ImageFrame::Pi
xelData); |
| 106 return NativeImageSkia::create(bitmap); |
| 101 } | 107 } |
| 102 if (m_actualDecoder) | 108 if (m_actualDecoder) { |
| 103 return m_actualDecoder->frameBufferAtIndex(index); | 109 ImageFrame* buffer = m_actualDecoder->frameBufferAtIndex(index); |
| 104 return 0; | 110 if (!buffer || buffer->status() == ImageFrame::FrameEmpty) |
| 111 return nullptr; |
| 112 return buffer->asNewNativeImage(); |
| 113 } |
| 114 return nullptr; |
| 105 } | 115 } |
| 106 | 116 |
| 107 void DeferredImageDecoder::setData(SharedBuffer& data, bool allDataReceived) | 117 void DeferredImageDecoder::setData(SharedBuffer& data, bool allDataReceived) |
| 108 { | 118 { |
| 109 if (m_actualDecoder) { | 119 if (m_actualDecoder) { |
| 110 const bool firstData = !m_data; | |
| 111 const bool moreData = data.size() > m_lastDataSize; | |
| 112 m_dataChanged = firstData || moreData; | |
| 113 m_data = RefPtr<SharedBuffer>(data); | 120 m_data = RefPtr<SharedBuffer>(data); |
| 114 m_lastDataSize = data.size(); | 121 m_lastDataSize = data.size(); |
| 115 m_allDataReceived = allDataReceived; | 122 m_allDataReceived = allDataReceived; |
| 116 m_actualDecoder->setData(&data, allDataReceived); | 123 m_actualDecoder->setData(&data, allDataReceived); |
| 117 prepareLazyDecodedFrames(); | 124 prepareLazyDecodedFrames(); |
| 118 } | 125 } |
| 119 | 126 |
| 120 if (m_frameGenerator) | 127 if (m_frameGenerator) |
| 121 m_frameGenerator->setData(&data, allDataReceived); | 128 m_frameGenerator->setData(&data, allDataReceived); |
| 122 } | 129 } |
| (...skipping 17 matching lines...) Expand all Loading... |
| 140 | 147 |
| 141 IntSize DeferredImageDecoder::frameSizeAtIndex(size_t index) const | 148 IntSize DeferredImageDecoder::frameSizeAtIndex(size_t index) const |
| 142 { | 149 { |
| 143 // FIXME: LocalFrame size is assumed to be uniform. This might not be true f
or | 150 // FIXME: LocalFrame size is assumed to be uniform. This might not be true f
or |
| 144 // future supported codecs. | 151 // future supported codecs. |
| 145 return m_actualDecoder ? m_actualDecoder->frameSizeAtIndex(index) : m_size; | 152 return m_actualDecoder ? m_actualDecoder->frameSizeAtIndex(index) : m_size; |
| 146 } | 153 } |
| 147 | 154 |
| 148 size_t DeferredImageDecoder::frameCount() | 155 size_t DeferredImageDecoder::frameCount() |
| 149 { | 156 { |
| 150 return m_actualDecoder ? m_actualDecoder->frameCount() : m_lazyDecodedFrames
.size(); | 157 return m_actualDecoder ? m_actualDecoder->frameCount() : m_frameData.size(); |
| 151 } | 158 } |
| 152 | 159 |
| 153 int DeferredImageDecoder::repetitionCount() const | 160 int DeferredImageDecoder::repetitionCount() const |
| 154 { | 161 { |
| 155 return m_actualDecoder ? m_actualDecoder->repetitionCount() : m_repetitionCo
unt; | 162 return m_actualDecoder ? m_actualDecoder->repetitionCount() : m_repetitionCo
unt; |
| 156 } | 163 } |
| 157 | 164 |
| 158 size_t DeferredImageDecoder::clearCacheExceptFrame(size_t clearExceptFrame) | 165 size_t DeferredImageDecoder::clearCacheExceptFrame(size_t clearExceptFrame) |
| 159 { | 166 { |
| 160 // If image decoding is deferred then frame buffer cache is managed by | 167 if (m_actualDecoder) |
| 161 // the compositor and this call is ignored. | 168 return m_actualDecoder->clearCacheExceptFrame(clearExceptFrame); |
| 162 return m_actualDecoder ? m_actualDecoder->clearCacheExceptFrame(clearExceptF
rame) : 0; | 169 size_t frameBytesCleared = 0; |
| 170 for (size_t i = 0; i < m_frameData.size(); ++i) { |
| 171 if (i != clearExceptFrame) { |
| 172 frameBytesCleared += m_frameData[i].m_frameBytes; |
| 173 m_frameData[i].m_frameBytes = 0; |
| 174 } |
| 175 } |
| 176 return frameBytesCleared; |
| 163 } | 177 } |
| 164 | 178 |
| 165 bool DeferredImageDecoder::frameHasAlphaAtIndex(size_t index) const | 179 bool DeferredImageDecoder::frameHasAlphaAtIndex(size_t index) const |
| 166 { | 180 { |
| 167 if (m_actualDecoder) | 181 if (m_actualDecoder) |
| 168 return m_actualDecoder->frameHasAlphaAtIndex(index); | 182 return m_actualDecoder->frameHasAlphaAtIndex(index); |
| 169 if (!m_frameGenerator->isMultiFrame()) | 183 if (!m_frameGenerator->isMultiFrame()) |
| 170 return m_frameGenerator->hasAlpha(index); | 184 return m_frameGenerator->hasAlpha(index); |
| 171 return true; | 185 return true; |
| 172 } | 186 } |
| 173 | 187 |
| 174 bool DeferredImageDecoder::frameIsCompleteAtIndex(size_t index) const | 188 bool DeferredImageDecoder::frameIsCompleteAtIndex(size_t index) const |
| 175 { | 189 { |
| 176 if (m_actualDecoder) | 190 if (m_actualDecoder) |
| 177 return m_actualDecoder->frameIsCompleteAtIndex(index); | 191 return m_actualDecoder->frameIsCompleteAtIndex(index); |
| 178 if (index < m_lazyDecodedFrames.size()) | 192 if (index < m_frameData.size()) |
| 179 return m_lazyDecodedFrames[index]->status() == ImageFrame::FrameComplete
; | 193 return m_frameData[index].m_isComplete; |
| 180 return false; | 194 return false; |
| 181 } | 195 } |
| 182 | 196 |
| 183 float DeferredImageDecoder::frameDurationAtIndex(size_t index) const | 197 float DeferredImageDecoder::frameDurationAtIndex(size_t index) const |
| 184 { | 198 { |
| 185 if (m_actualDecoder) | 199 if (m_actualDecoder) |
| 186 return m_actualDecoder->frameDurationAtIndex(index); | 200 return m_actualDecoder->frameDurationAtIndex(index); |
| 187 if (index < m_lazyDecodedFrames.size()) | 201 if (index < m_frameData.size()) |
| 188 return m_lazyDecodedFrames[index]->duration(); | 202 return m_frameData[index].m_duration; |
| 189 return 0; | 203 return 0; |
| 190 } | 204 } |
| 191 | 205 |
| 192 unsigned DeferredImageDecoder::frameBytesAtIndex(size_t index) const | 206 unsigned DeferredImageDecoder::frameBytesAtIndex(size_t index) const |
| 193 { | 207 { |
| 194 // If frame decoding is deferred then it is not managed by MemoryCache | 208 if (m_actualDecoder) |
| 195 // so return 0 here. | 209 return m_actualDecoder->frameBytesAtIndex(index); |
| 196 return m_frameGenerator ? 0 : m_actualDecoder->frameBytesAtIndex(index); | 210 if (index < m_frameData.size()) |
| 211 return m_frameData[index].m_frameBytes; |
| 212 return 0; |
| 197 } | 213 } |
| 198 | 214 |
| 199 ImageOrientation DeferredImageDecoder::orientation() const | 215 ImageOrientation DeferredImageDecoder::orientationAtIndex(size_t index) const |
| 200 { | 216 { |
| 201 return m_actualDecoder ? m_actualDecoder->orientation() : m_orientation; | 217 if (m_actualDecoder) |
| 218 return m_actualDecoder->orientation(); |
| 219 if (index < m_frameData.size()) |
| 220 return m_frameData[index].m_orientation; |
| 221 return DefaultImageOrientation; |
| 202 } | 222 } |
| 203 | 223 |
| 204 void DeferredImageDecoder::activateLazyDecoding() | 224 void DeferredImageDecoder::activateLazyDecoding() |
| 205 { | 225 { |
| 206 if (m_frameGenerator) | 226 if (m_frameGenerator) |
| 207 return; | 227 return; |
| 208 m_size = m_actualDecoder->size(); | 228 m_size = m_actualDecoder->size(); |
| 209 m_orientation = m_actualDecoder->orientation(); | |
| 210 m_filenameExtension = m_actualDecoder->filenameExtension(); | 229 m_filenameExtension = m_actualDecoder->filenameExtension(); |
| 211 m_hasColorProfile = m_actualDecoder->hasColorProfile(); | 230 m_hasColorProfile = m_actualDecoder->hasColorProfile(); |
| 212 const bool isSingleFrame = m_actualDecoder->repetitionCount() == cAnimationN
one || (m_allDataReceived && m_actualDecoder->frameCount() == 1u); | 231 const bool isSingleFrame = m_actualDecoder->repetitionCount() == cAnimationN
one || (m_allDataReceived && m_actualDecoder->frameCount() == 1u); |
| 213 m_frameGenerator = ImageFrameGenerator::create(SkISize::Make(m_actualDecoder
->decodedSize().width(), m_actualDecoder->decodedSize().height()), m_data, m_all
DataReceived, !isSingleFrame); | 232 m_frameGenerator = ImageFrameGenerator::create(SkISize::Make(m_actualDecoder
->decodedSize().width(), m_actualDecoder->decodedSize().height()), m_data, m_all
DataReceived, !isSingleFrame); |
| 214 } | 233 } |
| 215 | 234 |
| 216 void DeferredImageDecoder::prepareLazyDecodedFrames() | 235 void DeferredImageDecoder::prepareLazyDecodedFrames() |
| 217 { | 236 { |
| 218 if (!s_enabled | 237 if (!s_enabled |
| 219 || !m_actualDecoder | 238 || !m_actualDecoder |
| 220 || !m_actualDecoder->isSizeAvailable() | 239 || !m_actualDecoder->isSizeAvailable() |
| 221 || m_actualDecoder->filenameExtension() == "ico") | 240 || m_actualDecoder->filenameExtension() == "ico") |
| 222 return; | 241 return; |
| 223 | 242 |
| 224 activateLazyDecoding(); | 243 activateLazyDecoding(); |
| 225 | 244 |
| 226 const size_t previousSize = m_lazyDecodedFrames.size(); | 245 const size_t previousSize = m_frameData.size(); |
| 227 m_lazyDecodedFrames.resize(m_actualDecoder->frameCount()); | 246 m_frameData.resize(m_actualDecoder->frameCount()); |
| 228 | 247 |
| 229 // We have encountered a broken image file. Simply bail. | 248 // We have encountered a broken image file. Simply bail. |
| 230 if (m_lazyDecodedFrames.size() < previousSize) | 249 if (m_frameData.size() < previousSize) |
| 231 return; | 250 return; |
| 232 | 251 |
| 233 for (size_t i = previousSize; i < m_lazyDecodedFrames.size(); ++i) { | 252 for (size_t i = previousSize; i < m_frameData.size(); ++i) { |
| 234 OwnPtr<ImageFrame> frame(adoptPtr(new ImageFrame())); | 253 OwnPtr<ImageFrame> frame(adoptPtr(new ImageFrame())); |
| 235 frame->setSkBitmap(createBitmap(i)); | 254 m_frameData[i].m_haveMetadata = true; |
| 236 frame->setDuration(m_actualDecoder->frameDurationAtIndex(i)); | 255 m_frameData[i].m_duration = m_actualDecoder->frameDurationAtIndex(i); |
| 237 frame->setStatus(m_actualDecoder->frameIsCompleteAtIndex(i) ? ImageFrame
::FrameComplete : ImageFrame::FramePartial); | 256 m_frameData[i].m_orientation = m_actualDecoder->orientation(); |
| 238 m_lazyDecodedFrames[i] = frame.release(); | 257 m_frameData[i].m_isComplete = m_actualDecoder->frameIsCompleteAtIndex(i)
; |
| 239 } | 258 } |
| 240 | 259 |
| 241 // The last lazy decoded frame created from previous call might be | 260 // The last lazy decoded frame created from previous call might be |
| 242 // incomplete so update its state. | 261 // incomplete so update its state. |
| 243 if (previousSize) { | 262 if (previousSize) { |
| 244 const size_t lastFrame = previousSize - 1; | 263 const size_t lastFrame = previousSize - 1; |
| 245 m_lazyDecodedFrames[lastFrame]->setStatus(m_actualDecoder->frameIsComple
teAtIndex(lastFrame) ? ImageFrame::FrameComplete : ImageFrame::FramePartial); | 264 m_frameData[lastFrame].m_isComplete = m_actualDecoder->frameIsCompleteAt
Index(lastFrame); |
| 246 | |
| 247 // If data has changed then create a new bitmap. This forces | |
| 248 // Skia to decode again. | |
| 249 if (m_dataChanged) { | |
| 250 m_dataChanged = false; | |
| 251 m_lazyDecodedFrames[lastFrame]->setSkBitmap(createBitmap(lastFrame))
; | |
| 252 } | |
| 253 } | 265 } |
| 254 | 266 |
| 255 if (m_allDataReceived) { | 267 if (m_allDataReceived) { |
| 256 m_repetitionCount = m_actualDecoder->repetitionCount(); | 268 m_repetitionCount = m_actualDecoder->repetitionCount(); |
| 257 m_actualDecoder.clear(); | 269 m_actualDecoder.clear(); |
| 258 m_data = nullptr; | 270 m_data = nullptr; |
| 259 } | 271 } |
| 260 } | 272 } |
| 261 | 273 |
| 262 // Creates a SkBitmap that is backed by SkDiscardablePixelRef. | 274 // Creates a SkBitmap that is backed by SkDiscardablePixelRef. |
| 263 SkBitmap DeferredImageDecoder::createBitmap(size_t index) | 275 SkBitmap DeferredImageDecoder::createBitmap(size_t index) |
| 264 { | 276 { |
| 265 IntSize decodedSize = m_actualDecoder->decodedSize(); | 277 SkISize decodedSize = m_frameGenerator->getFullSize(); |
| 266 ASSERT(decodedSize.width() > 0); | 278 ASSERT(decodedSize.width() > 0); |
| 267 ASSERT(decodedSize.height() > 0); | 279 ASSERT(decodedSize.height() > 0); |
| 268 | 280 |
| 269 #if SK_B32_SHIFT // Little-endian RGBA pixels. (Android) | 281 #if SK_B32_SHIFT // Little-endian RGBA pixels. (Android) |
| 270 const SkColorType colorType = kRGBA_8888_SkColorType; | 282 const SkColorType colorType = kRGBA_8888_SkColorType; |
| 271 #else | 283 #else |
| 272 const SkColorType colorType = kBGRA_8888_SkColorType; | 284 const SkColorType colorType = kBGRA_8888_SkColorType; |
| 273 #endif | 285 #endif |
| 274 const SkImageInfo info = SkImageInfo::Make(decodedSize.width(), decodedSize.
height(), colorType, kPremul_SkAlphaType); | 286 const SkImageInfo info = SkImageInfo::Make(decodedSize.width(), decodedSize.
height(), colorType, kPremul_SkAlphaType); |
| 275 | 287 |
| 276 SkBitmap bitmap; | 288 SkBitmap bitmap; |
| 277 DecodingImageGenerator* generator = new DecodingImageGenerator(m_frameGenera
tor, info, index); | 289 DecodingImageGenerator* generator = new DecodingImageGenerator(m_frameGenera
tor, info, index); |
| 278 bool installed = SkInstallDiscardablePixelRef(generator, &bitmap); | 290 bool installed = SkInstallDiscardablePixelRef(generator, &bitmap); |
| 279 ASSERT_UNUSED(installed, installed); | 291 ASSERT_UNUSED(installed, installed); |
| 280 bitmap.pixelRef()->setURI(labelDiscardable); | 292 bitmap.pixelRef()->setURI(labelDiscardable); |
| 281 generator->setGenerationId(bitmap.getGenerationID()); | 293 generator->setGenerationId(bitmap.getGenerationID()); |
| 282 return bitmap; | 294 return bitmap; |
| 283 } | 295 } |
| 284 | 296 |
| 285 bool DeferredImageDecoder::hotSpot(IntPoint& hotSpot) const | 297 bool DeferredImageDecoder::hotSpot(IntPoint& hotSpot) const |
| 286 { | 298 { |
| 287 // TODO: Implement. | 299 // TODO: Implement. |
| 288 return m_actualDecoder ? m_actualDecoder->hotSpot(hotSpot) : false; | 300 return m_actualDecoder ? m_actualDecoder->hotSpot(hotSpot) : false; |
| 289 } | 301 } |
| 290 | 302 |
| 291 } // namespace blink | 303 } // namespace blink |
| OLD | NEW |