Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(271)

Side by Side Diff: third_party/WebKit/Source/platform/graphics/DeferredImageDecoder.cpp

Issue 1812273003: Eliminate copies of encoded image data (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix assertion Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
11 * documentation and/or other materials provided with the distribution. 11 * documentation and/or other materials provided with the distribution.
12 * 12 *
13 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY 13 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 */ 24 */
25 25
26 #include "platform/graphics/DeferredImageDecoder.h" 26 #include "platform/graphics/DeferredImageDecoder.h"
27 27
28 #include "platform/RuntimeEnabledFeatures.h" 28 #include "platform/RuntimeEnabledFeatures.h"
29 #include "platform/SharedBuffer.h"
29 #include "platform/graphics/DecodingImageGenerator.h" 30 #include "platform/graphics/DecodingImageGenerator.h"
30 #include "platform/graphics/FrameData.h" 31 #include "platform/graphics/FrameData.h"
31 #include "platform/graphics/ImageDecodingStore.h" 32 #include "platform/graphics/ImageDecodingStore.h"
32 #include "platform/graphics/ImageFrameGenerator.h" 33 #include "platform/graphics/ImageFrameGenerator.h"
34 #include "platform/image-decoders/SegmentReader.h"
33 #include "third_party/skia/include/core/SkImage.h" 35 #include "third_party/skia/include/core/SkImage.h"
34 #include "wtf/PassOwnPtr.h" 36 #include "wtf/PassOwnPtr.h"
35 37
36 namespace blink { 38 namespace blink {
37 39
38 bool DeferredImageDecoder::s_enabled = true; 40 bool DeferredImageDecoder::s_enabled = true;
39 41
40 PassOwnPtr<DeferredImageDecoder> DeferredImageDecoder::create(const SharedBuffer & data, ImageDecoder::AlphaOption alphaOption, ImageDecoder::GammaAndColorProfil eOption colorOptions) 42 PassOwnPtr<DeferredImageDecoder> DeferredImageDecoder::create(const SharedBuffer & data, ImageDecoder::AlphaOption alphaOption, ImageDecoder::GammaAndColorProfil eOption colorOptions)
41 { 43 {
42 OwnPtr<ImageDecoder> actualDecoder = ImageDecoder::create(data, alphaOption, colorOptions); 44 OwnPtr<ImageDecoder> actualDecoder = ImageDecoder::create(data, alphaOption, colorOptions);
43 45
44 if (!actualDecoder) 46 if (!actualDecoder)
45 return nullptr; 47 return nullptr;
46 48
47 return adoptPtr(new DeferredImageDecoder(actualDecoder.release())); 49 return adoptPtr(new DeferredImageDecoder(actualDecoder.release()));
48 } 50 }
49 51
50 PassOwnPtr<DeferredImageDecoder> DeferredImageDecoder::createForTesting(PassOwnP tr<ImageDecoder> actualDecoder) 52 PassOwnPtr<DeferredImageDecoder> DeferredImageDecoder::createForTesting(PassOwnP tr<ImageDecoder> actualDecoder)
51 { 53 {
52 return adoptPtr(new DeferredImageDecoder(std::move(actualDecoder))); 54 return adoptPtr(new DeferredImageDecoder(std::move(actualDecoder)));
53 } 55 }
54 56
55 DeferredImageDecoder::DeferredImageDecoder(PassOwnPtr<ImageDecoder> actualDecode r) 57 DeferredImageDecoder::DeferredImageDecoder(PassOwnPtr<ImageDecoder> actualDecode r)
56 : m_allDataReceived(false) 58 : m_allDataReceived(false)
57 , m_lastDataSize(0)
58 , m_actualDecoder(std::move(actualDecoder)) 59 , m_actualDecoder(std::move(actualDecoder))
59 , m_repetitionCount(cAnimationNone) 60 , m_repetitionCount(cAnimationNone)
60 , m_hasColorProfile(false) 61 , m_hasColorProfile(false)
61 , m_canYUVDecode(false) 62 , m_canYUVDecode(false)
62 { 63 {
63 } 64 }
64 65
65 DeferredImageDecoder::~DeferredImageDecoder() 66 DeferredImageDecoder::~DeferredImageDecoder()
66 { 67 {
67 } 68 }
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
104 ImageFrame* frame = m_actualDecoder->frameBufferAtIndex(index); 105 ImageFrame* frame = m_actualDecoder->frameBufferAtIndex(index);
105 if (!frame || frame->getStatus() == ImageFrame::FrameEmpty) 106 if (!frame || frame->getStatus() == ImageFrame::FrameEmpty)
106 return nullptr; 107 return nullptr;
107 108
108 return adoptRef(SkImage::NewFromBitmap(frame->bitmap())); 109 return adoptRef(SkImage::NewFromBitmap(frame->bitmap()));
109 } 110 }
110 111
111 void DeferredImageDecoder::setData(SharedBuffer& data, bool allDataReceived) 112 void DeferredImageDecoder::setData(SharedBuffer& data, bool allDataReceived)
112 { 113 {
113 if (m_actualDecoder) { 114 if (m_actualDecoder) {
114 m_data = RefPtr<SharedBuffer>(data);
115 m_lastDataSize = data.size();
116 m_allDataReceived = allDataReceived; 115 m_allDataReceived = allDataReceived;
117 m_actualDecoder->setData(&data, allDataReceived); 116 m_actualDecoder->setData(&data, allDataReceived);
118 prepareLazyDecodedFrames(); 117 prepareLazyDecodedFrames();
119 } 118 }
120 119
121 if (m_frameGenerator) 120 if (m_frameGenerator) {
122 m_frameGenerator->setData(&data, allDataReceived); 121 if (!m_rwBuffer)
122 m_rwBuffer = adoptPtr(new SkRWBuffer(data.size()));
123
124 const char* segment = 0;
125 while (size_t length = data.getSomeData(segment, m_rwBuffer->size()))
Peter Kasting 2016/03/25 06:24:36 Nit: Using side-effect statements in conditionals
scroggo 2016/03/25 15:49:52 :( Done. I considered using a do while loop: co
126 m_rwBuffer->append(segment, length);
127 }
123 } 128 }
124 129
125 bool DeferredImageDecoder::isSizeAvailable() 130 bool DeferredImageDecoder::isSizeAvailable()
126 { 131 {
127 // m_actualDecoder is 0 only if image decoding is deferred and that means 132 // m_actualDecoder is 0 only if image decoding is deferred and that means
128 // the image header decoded successfully and the size is available. 133 // the image header decoded successfully and the size is available.
129 return m_actualDecoder ? m_actualDecoder->isSizeAvailable() : true; 134 return m_actualDecoder ? m_actualDecoder->isSizeAvailable() : true;
130 } 135 }
131 136
132 bool DeferredImageDecoder::hasColorProfile() const 137 bool DeferredImageDecoder::hasColorProfile() const
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
220 if (m_frameGenerator) 225 if (m_frameGenerator)
221 return; 226 return;
222 227
223 m_size = m_actualDecoder->size(); 228 m_size = m_actualDecoder->size();
224 m_filenameExtension = m_actualDecoder->filenameExtension(); 229 m_filenameExtension = m_actualDecoder->filenameExtension();
225 // JPEG images support YUV decoding: other decoders do not, WEBP could in fu ture. 230 // JPEG images support YUV decoding: other decoders do not, WEBP could in fu ture.
226 m_canYUVDecode = RuntimeEnabledFeatures::decodeToYUVEnabled() && (m_filename Extension == "jpg"); 231 m_canYUVDecode = RuntimeEnabledFeatures::decodeToYUVEnabled() && (m_filename Extension == "jpg");
227 m_hasColorProfile = m_actualDecoder->hasColorProfile(); 232 m_hasColorProfile = m_actualDecoder->hasColorProfile();
228 233
229 const bool isSingleFrame = m_actualDecoder->repetitionCount() == cAnimationN one || (m_allDataReceived && m_actualDecoder->frameCount() == 1u); 234 const bool isSingleFrame = m_actualDecoder->repetitionCount() == cAnimationN one || (m_allDataReceived && m_actualDecoder->frameCount() == 1u);
230 m_frameGenerator = ImageFrameGenerator::create(SkISize::Make(m_actualDecoder ->decodedSize().width(), m_actualDecoder->decodedSize().height()), m_data, m_all DataReceived, !isSingleFrame); 235 const SkISize decodedSize = SkISize::Make(m_actualDecoder->decodedSize().wid th(), m_actualDecoder->decodedSize().height());
236 m_frameGenerator = ImageFrameGenerator::create(decodedSize, !isSingleFrame);
231 } 237 }
232 238
233 void DeferredImageDecoder::prepareLazyDecodedFrames() 239 void DeferredImageDecoder::prepareLazyDecodedFrames()
234 { 240 {
235 if (!s_enabled 241 if (!s_enabled
236 || !m_actualDecoder 242 || !m_actualDecoder
237 || !m_actualDecoder->isSizeAvailable() 243 || !m_actualDecoder->isSizeAvailable()
238 || m_actualDecoder->filenameExtension() == "ico") 244 || m_actualDecoder->filenameExtension() == "ico")
239 return; 245 return;
240 246
(...skipping 16 matching lines...) Expand all
257 // The last lazy decoded frame created from previous call might be 263 // The last lazy decoded frame created from previous call might be
258 // incomplete so update its state. 264 // incomplete so update its state.
259 if (previousSize) { 265 if (previousSize) {
260 const size_t lastFrame = previousSize - 1; 266 const size_t lastFrame = previousSize - 1;
261 m_frameData[lastFrame].m_isComplete = m_actualDecoder->frameIsCompleteAt Index(lastFrame); 267 m_frameData[lastFrame].m_isComplete = m_actualDecoder->frameIsCompleteAt Index(lastFrame);
262 } 268 }
263 269
264 if (m_allDataReceived) { 270 if (m_allDataReceived) {
265 m_repetitionCount = m_actualDecoder->repetitionCount(); 271 m_repetitionCount = m_actualDecoder->repetitionCount();
266 m_actualDecoder.clear(); 272 m_actualDecoder.clear();
267 m_data = nullptr; 273 // Hold on to the SkRWBuffer, which is still needed by createFrameAtInde x.
Peter Kasting 2016/03/25 06:24:36 Nit: the SkRWBuffer -> m_rwBuffer
scroggo 2016/03/25 15:49:52 Done.
268 } 274 }
269 } 275 }
270 276
271 inline SkImageInfo imageInfoFrom(const SkISize& decodedSize, bool knownToBeOpaqu e) 277 inline SkImageInfo imageInfoFrom(const SkISize& decodedSize, bool knownToBeOpaqu e)
272 { 278 {
273 return SkImageInfo::MakeN32(decodedSize.width(), decodedSize.height(), known ToBeOpaque ? kOpaque_SkAlphaType : kPremul_SkAlphaType); 279 return SkImageInfo::MakeN32(decodedSize.width(), decodedSize.height(), known ToBeOpaque ? kOpaque_SkAlphaType : kPremul_SkAlphaType);
274 } 280 }
275 281
276 PassRefPtr<SkImage> DeferredImageDecoder::createFrameImageAtIndex(size_t index, bool knownToBeOpaque) const 282 PassRefPtr<SkImage> DeferredImageDecoder::createFrameImageAtIndex(size_t index, bool knownToBeOpaque) const
277 { 283 {
278 const SkISize& decodedSize = m_frameGenerator->getFullSize(); 284 const SkISize& decodedSize = m_frameGenerator->getFullSize();
279 ASSERT(decodedSize.width() > 0); 285 ASSERT(decodedSize.width() > 0);
280 ASSERT(decodedSize.height() > 0); 286 ASSERT(decodedSize.height() > 0);
281 287
282 DecodingImageGenerator* generator = new DecodingImageGenerator(m_frameGenera tor, imageInfoFrom(decodedSize, knownToBeOpaque), index); 288 RefPtr<SkROBuffer> roBuffer = adoptRef(m_rwBuffer->newRBufferSnapshot());
289 RefPtr<SegmentReader> segmentReader = SegmentReader::createFromSkROBuffer(ro Buffer.release());
290 DecodingImageGenerator* generator = new DecodingImageGenerator(m_frameGenera tor, imageInfoFrom(decodedSize, knownToBeOpaque), segmentReader.release(), m_all DataReceived, index);
283 RefPtr<SkImage> image = adoptRef(SkImage::NewFromGenerator(generator)); // S kImage takes ownership of the generator. 291 RefPtr<SkImage> image = adoptRef(SkImage::NewFromGenerator(generator)); // S kImage takes ownership of the generator.
284 if (!image) 292 if (!image)
285 return nullptr; 293 return nullptr;
286 294
287 generator->setGenerationId(image->uniqueID()); 295 generator->setGenerationId(image->uniqueID());
288 generator->setCanYUVDecode(m_canYUVDecode); 296 generator->setCanYUVDecode(m_canYUVDecode);
289 297
290 return image.release(); 298 return image.release();
291 } 299 }
292 300
293 bool DeferredImageDecoder::hotSpot(IntPoint& hotSpot) const 301 bool DeferredImageDecoder::hotSpot(IntPoint& hotSpot) const
294 { 302 {
295 // TODO: Implement. 303 // TODO: Implement.
296 return m_actualDecoder ? m_actualDecoder->hotSpot(hotSpot) : false; 304 return m_actualDecoder ? m_actualDecoder->hotSpot(hotSpot) : false;
297 } 305 }
298 306
299 } // namespace blink 307 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698