+ // This method is called to populate a discardable memory owned by Skia.
+
+ // Prevents concurrent decode or scale operations on the same image data.
+ MutexLocker lock(m_decodeMutex);
+
+ if (m_decodeFailedAndEmpty)
+ return false;
+
+ TRACE_EVENT2("blink", "ImageFrameGenerator::decodeToYUV", "generator", this, "decodeCount", static_cast<int>(m_decodeCount));
+
+ if (!planes || !planes[0] || !planes[1] || !planes[2]
+ || !rowBytes || !rowBytes[0] || !rowBytes[1] || !rowBytes[2]) {
+ return false;
+ }
+
+ SharedBuffer* data = 0;
+ bool allDataReceived = false;
+ m_data.data(&data, &allDataReceived);
+
+ // FIXME: YUV decoding does not currently support progressive decoding.
+ ASSERT(allDataReceived);
+
+ OwnPtr<ImageDecoder> decoder = ImageDecoder::create(*data, ImageSource::AlphaPremultiplied, ImageSource::GammaAndColorProfileApplied);
+ if (!decoder)
+ return false;
+
+ decoder->setData(data, allDataReceived);
+
+ OwnPtr<ImagePlanes> imagePlanes = adoptPtr(new ImagePlanes(planes, rowBytes));
+ decoder->setImagePlanes(imagePlanes.release());
+
+ bool sizeUpdated = updateYUVComponentSizes(decoder.get(), componentSizes, ImageDecoder::ActualSize);
+ RELEASE_ASSERT(sizeUpdated);
+
+ bool yuvDecoded = decoder->decodeToYUV();
+ if (yuvDecoded)
+ setHasAlpha(0, false); // YUV is always opaque
+ return yuvDecoded;