Chromium Code Reviews| 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 18 matching lines...) Expand all Loading... | |
| 29 #include "platform/graphics/ImageDecodingStore.h" | 29 #include "platform/graphics/ImageDecodingStore.h" |
| 30 #include "platform/image-decoders/ImageDecoder.h" | 30 #include "platform/image-decoders/ImageDecoder.h" |
| 31 #include "platform/instrumentation/tracing/TraceEvent.h" | 31 #include "platform/instrumentation/tracing/TraceEvent.h" |
| 32 #include "third_party/skia/include/core/SkYUVSizeInfo.h" | 32 #include "third_party/skia/include/core/SkYUVSizeInfo.h" |
| 33 #include "wtf/PtrUtil.h" | 33 #include "wtf/PtrUtil.h" |
| 34 #include <memory> | 34 #include <memory> |
| 35 | 35 |
| 36 namespace blink { | 36 namespace blink { |
| 37 | 37 |
| 38 static bool compatibleInfo(const SkImageInfo& src, const SkImageInfo& dst) { | 38 static bool compatibleInfo(const SkImageInfo& src, const SkImageInfo& dst) { |
| 39 if (src == dst) | 39 bool compatibleSize = src.dimensions() == dst.dimensions(); |
| 40 return true; | 40 bool compatibleColorType = src.colorType() == dst.colorType(); |
| 41 | 41 |
| 42 // It is legal to write kOpaque_SkAlphaType pixels into a kPremul_SkAlphaType | 42 // We should be lenient with alphaType. Any image can be decoded to kUnpremul |
| 43 // buffer. This can happen when DeferredImageDecoder allocates an | 43 // or kPremul. Opaque images may be marked as kOpaque, but not until they |
| 44 // kOpaque_SkAlphaType image generator based on cached frame info, while the | 44 // are fully decoded. This means that the buffer may be kPremul, but we are |
| 45 // ImageFrame-allocated dest bitmap stays kPremul_SkAlphaType. | 45 // writing kOpaque pixels. |
| 46 if (src.alphaType() == kOpaque_SkAlphaType && | |
| 47 dst.alphaType() == kPremul_SkAlphaType) { | |
| 48 const SkImageInfo& tmp = src.makeAlphaType(kPremul_SkAlphaType); | |
| 49 return tmp == dst; | |
| 50 } | |
| 51 | 46 |
| 52 return false; | 47 // The color spaces also do not need to match. We will perform color space |
| 48 // conversions when necessary. | |
| 49 | |
| 50 return compatibleSize && compatibleColorType; | |
| 53 } | 51 } |
| 54 | 52 |
| 55 // Creates a SkPixelRef such that the memory for pixels is given by an external | 53 // Creates a SkPixelRef such that the memory for pixels is given by an external |
| 56 // body. This is used to write directly to the memory given by Skia during | 54 // body. This is used to write directly to the memory given by Skia during |
| 57 // decoding. | 55 // decoding. |
| 58 class ExternalMemoryAllocator final : public SkBitmap::Allocator { | 56 class ExternalMemoryAllocator final : public SkBitmap::Allocator { |
| 59 USING_FAST_MALLOC(ExternalMemoryAllocator); | 57 USING_FAST_MALLOC(ExternalMemoryAllocator); |
| 60 WTF_MAKE_NONCOPYABLE(ExternalMemoryAllocator); | 58 WTF_MAKE_NONCOPYABLE(ExternalMemoryAllocator); |
| 61 | 59 |
| 62 public: | 60 public: |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 96 componentWidthBytes[0] = decoder->decodedYUVWidthBytes(0); | 94 componentWidthBytes[0] = decoder->decodedYUVWidthBytes(0); |
| 97 size = decoder->decodedYUVSize(1); | 95 size = decoder->decodedYUVSize(1); |
| 98 componentSizes[1].set(size.width(), size.height()); | 96 componentSizes[1].set(size.width(), size.height()); |
| 99 componentWidthBytes[1] = decoder->decodedYUVWidthBytes(1); | 97 componentWidthBytes[1] = decoder->decodedYUVWidthBytes(1); |
| 100 size = decoder->decodedYUVSize(2); | 98 size = decoder->decodedYUVSize(2); |
| 101 componentSizes[2].set(size.width(), size.height()); | 99 componentSizes[2].set(size.width(), size.height()); |
| 102 componentWidthBytes[2] = decoder->decodedYUVWidthBytes(2); | 100 componentWidthBytes[2] = decoder->decodedYUVWidthBytes(2); |
| 103 return true; | 101 return true; |
| 104 } | 102 } |
| 105 | 103 |
| 106 ImageFrameGenerator::ImageFrameGenerator(const SkISize& fullSize, | 104 ImageFrameGenerator::ImageFrameGenerator(const SkImageInfo& info, |
| 107 bool isMultiFrame, | 105 bool isMultiFrame, |
| 108 const ColorBehavior& colorBehavior) | 106 const ColorBehavior& colorBehavior) |
| 109 : m_fullSize(fullSize), | 107 : m_info(info), |
| 110 m_decoderColorBehavior(colorBehavior), | 108 m_decoderColorBehavior(colorBehavior), |
| 111 m_isMultiFrame(isMultiFrame), | 109 m_isMultiFrame(isMultiFrame), |
| 112 m_decodeFailed(false), | 110 m_decodeFailed(false), |
| 113 m_yuvDecodingFailed(false), | 111 m_yuvDecodingFailed(false), |
| 114 m_frameCount(0) {} | 112 m_frameCount(0) {} |
| 115 | 113 |
| 116 ImageFrameGenerator::~ImageFrameGenerator() { | 114 ImageFrameGenerator::~ImageFrameGenerator() { |
| 117 ImageDecodingStore::instance().removeCacheIndexedByGenerator(this); | 115 ImageDecodingStore::instance().removeCacheIndexedByGenerator(this); |
| 118 } | 116 } |
| 119 | 117 |
| 120 bool ImageFrameGenerator::decodeAndScale(SegmentReader* data, | 118 bool ImageFrameGenerator::decodeAndScale(SegmentReader* data, |
| 121 bool allDataReceived, | 119 bool allDataReceived, |
| 122 size_t index, | 120 size_t index, |
| 123 const SkImageInfo& info, | 121 const SkImageInfo& dstInfo, |
| 124 void* pixels, | 122 void* pixels, |
| 125 size_t rowBytes) { | 123 size_t rowBytes) { |
| 126 if (m_decodeFailed) | 124 if (m_decodeFailed) |
| 127 return false; | 125 return false; |
| 128 | 126 |
| 129 TRACE_EVENT1("blink", "ImageFrameGenerator::decodeAndScale", "frame index", | 127 TRACE_EVENT1("blink", "ImageFrameGenerator::decodeAndScale", "frame index", |
| 130 static_cast<int>(index)); | 128 static_cast<int>(index)); |
| 131 | 129 |
| 132 // This implementation does not support scaling so check the requested size. | 130 // This implementation does not support scaling so check the requested size. |
| 133 SkISize scaledSize = SkISize::Make(info.width(), info.height()); | 131 SkISize scaledSize = SkISize::Make(dstInfo.width(), dstInfo.height()); |
| 134 ASSERT(m_fullSize == scaledSize); | 132 DCHECK(m_info.dimensions() == scaledSize); |
|
scroggo_chromium
2017/04/07 18:06:06
scaledSize looks to be never used again (or it doe
| |
| 135 | 133 |
| 136 // It is okay to allocate ref-counted ExternalMemoryAllocator on the stack, | 134 // It is okay to allocate ref-counted ExternalMemoryAllocator on the stack, |
| 137 // because 1) it contains references to memory that will be invalid after | 135 // because 1) it contains references to memory that will be invalid after |
| 138 // returning (i.e. a pointer to |pixels|) and therefore 2) should not live | 136 // returning (i.e. a pointer to |pixels|) and therefore 2) should not live |
| 139 // longer than the call to the current method. | 137 // longer than the call to the current method. |
| 140 ExternalMemoryAllocator externalAllocator(info, pixels, rowBytes); | 138 ExternalMemoryAllocator externalAllocator(dstInfo, pixels, rowBytes); |
| 141 SkBitmap bitmap = tryToResumeDecode(data, allDataReceived, index, scaledSize, | 139 SkBitmap bitmap = tryToResumeDecode(data, allDataReceived, index, scaledSize, |
| 142 &externalAllocator); | 140 &externalAllocator, dstInfo); |
| 143 DCHECK(externalAllocator.unique()); // Verify we have the only ref-count. | 141 DCHECK(externalAllocator.unique()); // Verify we have the only ref-count. |
| 144 | 142 |
| 145 if (bitmap.isNull()) | 143 if (bitmap.isNull()) |
| 146 return false; | 144 return false; |
| 147 | 145 |
| 148 // Check to see if the decoder has written directly to the pixel memory | 146 // Check to see if the decoder has written directly to the pixel memory |
| 149 // provided. If not, make a copy. | 147 // provided. If not, make a copy. |
| 150 ASSERT(bitmap.width() == scaledSize.width()); | 148 ASSERT(bitmap.width() == scaledSize.width()); |
|
scroggo_chromium
2017/04/07 18:06:06
If you drop scaledSize, this could be:
DCHECK_E
| |
| 151 ASSERT(bitmap.height() == scaledSize.height()); | 149 ASSERT(bitmap.height() == scaledSize.height()); |
| 152 SkAutoLockPixels bitmapLock(bitmap); | 150 SkAutoLockPixels bitmapLock(bitmap); |
| 153 if (bitmap.getPixels() != pixels) | 151 if (bitmap.getPixels() != pixels) |
| 154 return bitmap.copyPixelsTo(pixels, rowBytes * info.height(), rowBytes); | 152 return bitmap.readPixels(bitmap.info(), pixels, rowBytes, 0, 0); |
|
scroggo_chromium
2017/04/07 18:06:06
Might bitmap.info() be different from dstInfo? I'm
| |
| 155 return true; | 153 return true; |
| 156 } | 154 } |
| 157 | 155 |
| 158 bool ImageFrameGenerator::decodeToYUV(SegmentReader* data, | 156 bool ImageFrameGenerator::decodeToYUV(SegmentReader* data, |
| 159 size_t index, | 157 size_t index, |
| 160 const SkISize componentSizes[3], | 158 const SkISize componentSizes[3], |
| 161 void* planes[3], | 159 void* planes[3], |
| 162 const size_t rowBytes[3]) { | 160 const size_t rowBytes[3]) { |
| 163 // TODO (scroggo): The only interesting thing this uses from the | 161 // TODO (scroggo): The only interesting thing this uses from the |
| 164 // ImageFrameGenerator is m_decodeFailed. Move this into | 162 // ImageFrameGenerator is m_decodeFailed. Move this into |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 189 if (decoder->decodeToYUV()) { | 187 if (decoder->decodeToYUV()) { |
| 190 setHasAlpha(0, false); // YUV is always opaque | 188 setHasAlpha(0, false); // YUV is always opaque |
| 191 return true; | 189 return true; |
| 192 } | 190 } |
| 193 | 191 |
| 194 ASSERT(decoder->failed()); | 192 ASSERT(decoder->failed()); |
| 195 m_yuvDecodingFailed = true; | 193 m_yuvDecodingFailed = true; |
| 196 return false; | 194 return false; |
| 197 } | 195 } |
| 198 | 196 |
| 199 SkBitmap ImageFrameGenerator::tryToResumeDecode( | 197 static inline bool needsColorXform(const SkImageInfo& src, |
| 200 SegmentReader* data, | 198 const SkImageInfo& dst) { |
| 201 bool allDataReceived, | 199 return src.colorSpace() && dst.colorSpace() && |
| 202 size_t index, | 200 !SkColorSpace::Equals(src.colorSpace(), dst.colorSpace()); |
| 203 const SkISize& scaledSize, | 201 } |
| 204 SkBitmap::Allocator* allocator) { | 202 |
| 203 SkBitmap ImageFrameGenerator::tryToResumeDecode(SegmentReader* data, | |
| 204 bool allDataReceived, | |
| 205 size_t index, | |
| 206 const SkISize& scaledSize, | |
| 207 SkBitmap::Allocator* allocator, | |
| 208 const SkImageInfo& dstInfo) { | |
| 205 TRACE_EVENT1("blink", "ImageFrameGenerator::tryToResumeDecode", "frame index", | 209 TRACE_EVENT1("blink", "ImageFrameGenerator::tryToResumeDecode", "frame index", |
| 206 static_cast<int>(index)); | 210 static_cast<int>(index)); |
| 207 | 211 |
| 208 ImageDecoder* decoder = 0; | 212 ImageDecoder* decoder = 0; |
| 209 | 213 |
| 214 const bool needsXform = needsColorXform(m_info, dstInfo); | |
| 215 ImageDecoder::AlphaOption alphaOption = ImageDecoder::AlphaPremultiplied; | |
| 216 if (needsXform && !dstInfo.isOpaque()) { | |
|
scroggo_chromium
2017/04/07 18:06:06
It might be worth noting that you check dstInfo be
msarett1
2017/04/10 14:42:46
Acknowledged.
| |
| 217 alphaOption = ImageDecoder::AlphaNotPremultiplied; | |
| 218 } | |
| 219 | |
| 210 // Lock the mutex, so only one thread can use the decoder at once. | 220 // Lock the mutex, so only one thread can use the decoder at once. |
| 211 MutexLocker lock(m_decodeMutex); | 221 MutexLocker lock(m_decodeMutex); |
| 212 const bool resumeDecoding = | 222 const bool resumeDecoding = ImageDecodingStore::instance().lockDecoder( |
| 213 ImageDecodingStore::instance().lockDecoder(this, m_fullSize, &decoder); | 223 this, m_info.dimensions(), alphaOption, &decoder); |
| 214 ASSERT(!resumeDecoding || decoder); | 224 ASSERT(!resumeDecoding || decoder); |
| 215 | 225 |
| 216 SkBitmap fullSizeImage; | 226 SkBitmap fullSizeImage; |
| 217 bool complete = | 227 bool complete = decode(data, allDataReceived, index, &decoder, &fullSizeImage, |
| 218 decode(data, allDataReceived, index, &decoder, &fullSizeImage, allocator); | 228 allocator, alphaOption, dstInfo); |
| 219 | 229 |
| 220 if (!decoder) | 230 if (!decoder) |
| 221 return SkBitmap(); | 231 return SkBitmap(); |
| 222 | 232 |
| 223 // If we are not resuming decoding that means the decoder is freshly | 233 // If we are not resuming decoding that means the decoder is freshly |
| 224 // created and we have ownership. If we are resuming decoding then | 234 // created and we have ownership. If we are resuming decoding then |
| 225 // the decoder is owned by ImageDecodingStore. | 235 // the decoder is owned by ImageDecodingStore. |
| 226 std::unique_ptr<ImageDecoder> decoderContainer; | 236 std::unique_ptr<ImageDecoder> decoderContainer; |
| 227 if (!resumeDecoding) | 237 if (!resumeDecoding) |
| 228 decoderContainer = WTF::wrapUnique(decoder); | 238 decoderContainer = WTF::wrapUnique(decoder); |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 273 m_hasAlpha[i] = true; | 283 m_hasAlpha[i] = true; |
| 274 } | 284 } |
| 275 m_hasAlpha[index] = hasAlpha; | 285 m_hasAlpha[index] = hasAlpha; |
| 276 } | 286 } |
| 277 | 287 |
| 278 bool ImageFrameGenerator::decode(SegmentReader* data, | 288 bool ImageFrameGenerator::decode(SegmentReader* data, |
| 279 bool allDataReceived, | 289 bool allDataReceived, |
| 280 size_t index, | 290 size_t index, |
| 281 ImageDecoder** decoder, | 291 ImageDecoder** decoder, |
| 282 SkBitmap* bitmap, | 292 SkBitmap* bitmap, |
| 283 SkBitmap::Allocator* allocator) { | 293 SkBitmap::Allocator* allocator, |
| 294 ImageDecoder::AlphaOption alphaOption, | |
| 295 const SkImageInfo& dstInfo) { | |
| 284 ASSERT(m_decodeMutex.locked()); | 296 ASSERT(m_decodeMutex.locked()); |
| 285 TRACE_EVENT2("blink", "ImageFrameGenerator::decode", "width", | 297 TRACE_EVENT2("blink", "ImageFrameGenerator::decode", "width", m_info.width(), |
| 286 m_fullSize.width(), "height", m_fullSize.height()); | 298 "height", m_info.height()); |
| 287 | 299 |
| 288 // Try to create an ImageDecoder if we are not given one. | 300 // Try to create an ImageDecoder if we are not given one. |
| 289 ASSERT(decoder); | 301 ASSERT(decoder); |
| 290 bool newDecoder = false; | 302 bool newDecoder = false; |
| 291 bool shouldCallSetData = true; | 303 bool shouldCallSetData = true; |
| 292 if (!*decoder) { | 304 if (!*decoder) { |
| 293 newDecoder = true; | 305 newDecoder = true; |
| 294 if (m_imageDecoderFactory) | 306 if (m_imageDecoderFactory) |
| 295 *decoder = m_imageDecoderFactory->create().release(); | 307 *decoder = m_imageDecoderFactory->create().release(); |
| 296 | 308 |
| 297 if (!*decoder) { | 309 if (!*decoder) { |
| 298 *decoder = ImageDecoder::create(data, allDataReceived, | 310 *decoder = ImageDecoder::create(data, allDataReceived, alphaOption, |
| 299 ImageDecoder::AlphaPremultiplied, | |
| 300 m_decoderColorBehavior) | 311 m_decoderColorBehavior) |
| 301 .release(); | 312 .release(); |
| 302 // The newly created decoder just grabbed the data. No need to reset it. | 313 // The newly created decoder just grabbed the data. No need to reset it. |
| 303 shouldCallSetData = false; | 314 shouldCallSetData = false; |
| 304 } | 315 } |
| 305 | 316 |
| 306 if (!*decoder) | 317 if (!*decoder) |
| 307 return false; | 318 return false; |
| 308 } | 319 } |
| 309 | 320 |
| 310 | |
| 311 if (shouldCallSetData) | 321 if (shouldCallSetData) |
| 312 (*decoder)->setData(data, allDataReceived); | 322 (*decoder)->setData(data, allDataReceived); |
| 313 | 323 |
| 314 bool usingExternalAllocator = false; | 324 bool usingExternalAllocator = false; |
| 315 | 325 |
| 316 // For multi-frame image decoders, we need to know how many frames are | 326 // For multi-frame image decoders, we need to know how many frames are |
| 317 // in that image in order to release the decoder when all frames are | 327 // in that image in order to release the decoder when all frames are |
| 318 // decoded. frameCount() is reliable only if all data is received and set in | 328 // decoded. frameCount() is reliable only if all data is received and set in |
| 319 // decoder, particularly with GIF. | 329 // decoder, particularly with GIF. |
| 320 if (allDataReceived) { | 330 if (allDataReceived) { |
| (...skipping 22 matching lines...) Expand all Loading... | |
| 343 return false; | 353 return false; |
| 344 | 354 |
| 345 // A cache object is considered complete if we can decode a complete frame. | 355 // A cache object is considered complete if we can decode a complete frame. |
| 346 // Or we have received all data. The image might not be fully decoded in | 356 // Or we have received all data. The image might not be fully decoded in |
| 347 // the latter case. | 357 // the latter case. |
| 348 const bool isDecodeComplete = | 358 const bool isDecodeComplete = |
| 349 frame->getStatus() == ImageFrame::FrameComplete || allDataReceived; | 359 frame->getStatus() == ImageFrame::FrameComplete || allDataReceived; |
| 350 | 360 |
| 351 SkBitmap fullSizeBitmap = frame->bitmap(); | 361 SkBitmap fullSizeBitmap = frame->bitmap(); |
| 352 if (!fullSizeBitmap.isNull()) { | 362 if (!fullSizeBitmap.isNull()) { |
| 353 ASSERT(fullSizeBitmap.width() == m_fullSize.width() && | 363 DCHECK(fullSizeBitmap.width() == m_info.width() && |
|
scroggo_chromium
2017/04/07 18:06:06
So long as you're changing this, it could be:
D
msarett1
2017/04/10 14:42:46
Acknowledged.
| |
| 354 fullSizeBitmap.height() == m_fullSize.height()); | 364 fullSizeBitmap.height() == m_info.height()); |
| 355 setHasAlpha(index, !fullSizeBitmap.isOpaque()); | 365 setHasAlpha(index, !fullSizeBitmap.isOpaque()); |
| 356 } | 366 } |
| 357 | 367 |
| 368 if (needsColorXform(m_info, dstInfo)) { | |
|
scroggo_chromium
2017/04/07 18:06:06
I assume you do not need to do this if fullSizeBit
msarett1
2017/04/10 14:42:46
Acknowledged.
| |
| 369 DCHECK(dstInfo.isOpaque() || | |
| 370 ImageDecoder::AlphaNotPremultiplied == alphaOption); | |
| 371 std::unique_ptr<SkColorSpaceXform> xform = | |
| 372 SkColorSpaceXform::New(m_info.colorSpace(), dstInfo.colorSpace()); | |
| 373 | |
| 374 SkBitmap tmp(fullSizeBitmap); | |
|
scroggo_chromium
2017/04/07 18:06:06
IIRC, this will make tmp share fullSizeBitmap's Sk
msarett1
2017/04/10 14:42:46
Acknowledged.
| |
| 375 tmp.lockPixels(); | |
| 376 uint32_t* row = tmp.getAddr32(0, 0); | |
| 377 for (int y = 0; y < dstInfo.height(); y++) { | |
|
scroggo_chromium
2017/04/07 18:06:06
This method is called while m_decodeMutex is locke
msarett1
2017/04/10 14:42:45
Acknowledged.
| |
| 378 SkColorSpaceXform::ColorFormat format = | |
| 379 SkColorSpaceXform::kRGBA_8888_ColorFormat; | |
| 380 if (kN32_SkColorType == kBGRA_8888_SkColorType) { | |
| 381 format = SkColorSpaceXform::kBGRA_8888_ColorFormat; | |
| 382 } | |
| 383 SkAlphaType alphaType = | |
| 384 dstInfo.isOpaque() ? kOpaque_SkAlphaType : kUnpremul_SkAlphaType; | |
|
scroggo_chromium
2017/04/07 18:06:06
My first thought was that you could use dstInfo.al
msarett1
2017/04/10 14:42:46
Acknowledged.
| |
| 385 bool xformed = | |
| 386 xform->apply(format, row, format, row, dstInfo.width(), alphaType); | |
| 387 DCHECK(xformed); | |
| 388 | |
| 389 // To be compatible with dst space blending, premultiply in the dst space. | |
| 390 if (kPremul_SkAlphaType == dstInfo.alphaType()) { | |
| 391 for (int x = 0; x < dstInfo.width(); x++) { | |
| 392 row[x] = | |
| 393 SkPreMultiplyARGB(SkGetPackedA32(row[x]), SkGetPackedR32(row[x]), | |
| 394 SkGetPackedG32(row[x]), SkGetPackedB32(row[x])); | |
| 395 } | |
| 396 } | |
| 397 | |
| 398 row = (uint32_t*)(((uint8_t*)row) + fullSizeBitmap.rowBytes()); | |
|
scroggo_chromium
2017/04/07 18:06:06
I think tmp and fullSizeBitmap are essentially the
msarett1
2017/04/10 14:42:46
Acknowledged.
| |
| 399 } | |
| 400 } | |
| 401 | |
| 358 *bitmap = fullSizeBitmap; | 402 *bitmap = fullSizeBitmap; |
| 359 return isDecodeComplete; | 403 return isDecodeComplete; |
| 360 } | 404 } |
| 361 | 405 |
| 362 bool ImageFrameGenerator::hasAlpha(size_t index) { | 406 bool ImageFrameGenerator::hasAlpha(size_t index) { |
| 363 MutexLocker lock(m_alphaMutex); | 407 MutexLocker lock(m_alphaMutex); |
| 364 if (index < m_hasAlpha.size()) | 408 if (index < m_hasAlpha.size()) |
| 365 return m_hasAlpha[index]; | 409 return m_hasAlpha[index]; |
| 366 return true; | 410 return true; |
| 367 } | 411 } |
| 368 | 412 |
| 369 bool ImageFrameGenerator::getYUVComponentSizes(SegmentReader* data, | 413 bool ImageFrameGenerator::getYUVComponentSizes(SegmentReader* data, |
| 370 SkYUVSizeInfo* sizeInfo) { | 414 SkYUVSizeInfo* sizeInfo) { |
| 371 TRACE_EVENT2("blink", "ImageFrameGenerator::getYUVComponentSizes", "width", | 415 TRACE_EVENT2("blink", "ImageFrameGenerator::getYUVComponentSizes", "width", |
| 372 m_fullSize.width(), "height", m_fullSize.height()); | 416 m_info.width(), "height", m_info.height()); |
| 373 | 417 |
| 374 if (m_yuvDecodingFailed) | 418 if (m_yuvDecodingFailed) |
| 375 return false; | 419 return false; |
| 376 | 420 |
| 377 std::unique_ptr<ImageDecoder> decoder = ImageDecoder::create( | 421 std::unique_ptr<ImageDecoder> decoder = ImageDecoder::create( |
| 378 data, true, ImageDecoder::AlphaPremultiplied, m_decoderColorBehavior); | 422 data, true, ImageDecoder::AlphaPremultiplied, m_decoderColorBehavior); |
| 379 if (!decoder) | 423 if (!decoder) |
| 380 return false; | 424 return false; |
| 381 | 425 |
| 382 // Setting a dummy ImagePlanes object signals to the decoder that we want to | 426 // Setting a dummy ImagePlanes object signals to the decoder that we want to |
| 383 // do YUV decoding. | 427 // do YUV decoding. |
| 384 std::unique_ptr<ImagePlanes> dummyImagePlanes = | 428 std::unique_ptr<ImagePlanes> dummyImagePlanes = |
| 385 WTF::wrapUnique(new ImagePlanes); | 429 WTF::wrapUnique(new ImagePlanes); |
| 386 decoder->setImagePlanes(std::move(dummyImagePlanes)); | 430 decoder->setImagePlanes(std::move(dummyImagePlanes)); |
| 387 | 431 |
| 388 return updateYUVComponentSizes(decoder.get(), sizeInfo->fSizes, | 432 return updateYUVComponentSizes(decoder.get(), sizeInfo->fSizes, |
| 389 sizeInfo->fWidthBytes); | 433 sizeInfo->fWidthBytes); |
| 390 } | 434 } |
| 391 | 435 |
| 392 } // namespace blink | 436 } // namespace blink |
| OLD | NEW |