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

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: Rebase Created 4 years, 8 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 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
107 ImageFrame* frame = m_actualDecoder->frameBufferAtIndex(index); 108 ImageFrame* frame = m_actualDecoder->frameBufferAtIndex(index);
108 if (!frame || frame->getStatus() == ImageFrame::FrameEmpty) 109 if (!frame || frame->getStatus() == ImageFrame::FrameEmpty)
109 return nullptr; 110 return nullptr;
110 111
111 return adoptRef(SkImage::NewFromBitmap(frame->bitmap())); 112 return adoptRef(SkImage::NewFromBitmap(frame->bitmap()));
112 } 113 }
113 114
114 void DeferredImageDecoder::setData(SharedBuffer& data, bool allDataReceived) 115 void DeferredImageDecoder::setData(SharedBuffer& data, bool allDataReceived)
115 { 116 {
116 if (m_actualDecoder) { 117 if (m_actualDecoder) {
117 m_data = RefPtr<SharedBuffer>(data);
118 m_lastDataSize = data.size();
119 m_allDataReceived = allDataReceived; 118 m_allDataReceived = allDataReceived;
120 m_actualDecoder->setData(&data, allDataReceived); 119 m_actualDecoder->setData(&data, allDataReceived);
121 prepareLazyDecodedFrames(); 120 prepareLazyDecodedFrames();
122 } 121 }
123 122
124 if (m_frameGenerator) 123 if (m_frameGenerator) {
125 m_frameGenerator->setData(&data, allDataReceived); 124 if (!m_rwBuffer)
125 m_rwBuffer = adoptPtr(new SkRWBuffer(data.size()));
126
127 const char* segment = 0;
128 for (size_t length = data.getSomeData(segment, m_rwBuffer->size());
129 length; length = data.getSomeData(segment, m_rwBuffer->size()))
130 m_rwBuffer->append(segment, length);
131 }
126 } 132 }
127 133
128 bool DeferredImageDecoder::isSizeAvailable() 134 bool DeferredImageDecoder::isSizeAvailable()
129 { 135 {
130 // m_actualDecoder is 0 only if image decoding is deferred and that means 136 // m_actualDecoder is 0 only if image decoding is deferred and that means
131 // the image header decoded successfully and the size is available. 137 // the image header decoded successfully and the size is available.
132 return m_actualDecoder ? m_actualDecoder->isSizeAvailable() : true; 138 return m_actualDecoder ? m_actualDecoder->isSizeAvailable() : true;
133 } 139 }
134 140
135 bool DeferredImageDecoder::hasColorProfile() const 141 bool DeferredImageDecoder::hasColorProfile() const
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
223 if (m_frameGenerator) 229 if (m_frameGenerator)
224 return; 230 return;
225 231
226 m_size = m_actualDecoder->size(); 232 m_size = m_actualDecoder->size();
227 m_filenameExtension = m_actualDecoder->filenameExtension(); 233 m_filenameExtension = m_actualDecoder->filenameExtension();
228 // JPEG images support YUV decoding: other decoders do not, WEBP could in fu ture. 234 // JPEG images support YUV decoding: other decoders do not, WEBP could in fu ture.
229 m_canYUVDecode = RuntimeEnabledFeatures::decodeToYUVEnabled() && (m_filename Extension == "jpg"); 235 m_canYUVDecode = RuntimeEnabledFeatures::decodeToYUVEnabled() && (m_filename Extension == "jpg");
230 m_hasColorProfile = m_actualDecoder->hasColorProfile(); 236 m_hasColorProfile = m_actualDecoder->hasColorProfile();
231 237
232 const bool isSingleFrame = m_actualDecoder->repetitionCount() == cAnimationN one || (m_allDataReceived && m_actualDecoder->frameCount() == 1u); 238 const bool isSingleFrame = m_actualDecoder->repetitionCount() == cAnimationN one || (m_allDataReceived && m_actualDecoder->frameCount() == 1u);
233 m_frameGenerator = ImageFrameGenerator::create(SkISize::Make(m_actualDecoder ->decodedSize().width(), m_actualDecoder->decodedSize().height()), m_data, m_all DataReceived, !isSingleFrame); 239 const SkISize decodedSize = SkISize::Make(m_actualDecoder->decodedSize().wid th(), m_actualDecoder->decodedSize().height());
240 m_frameGenerator = ImageFrameGenerator::create(decodedSize, !isSingleFrame);
234 } 241 }
235 242
236 void DeferredImageDecoder::prepareLazyDecodedFrames() 243 void DeferredImageDecoder::prepareLazyDecodedFrames()
237 { 244 {
238 if (!s_enabled 245 if (!s_enabled
239 || !m_actualDecoder 246 || !m_actualDecoder
240 || !m_actualDecoder->isSizeAvailable() 247 || !m_actualDecoder->isSizeAvailable()
241 || m_actualDecoder->filenameExtension() == "ico") 248 || m_actualDecoder->filenameExtension() == "ico")
242 return; 249 return;
243 250
(...skipping 16 matching lines...) Expand all
260 // The last lazy decoded frame created from previous call might be 267 // The last lazy decoded frame created from previous call might be
261 // incomplete so update its state. 268 // incomplete so update its state.
262 if (previousSize) { 269 if (previousSize) {
263 const size_t lastFrame = previousSize - 1; 270 const size_t lastFrame = previousSize - 1;
264 m_frameData[lastFrame].m_isComplete = m_actualDecoder->frameIsCompleteAt Index(lastFrame); 271 m_frameData[lastFrame].m_isComplete = m_actualDecoder->frameIsCompleteAt Index(lastFrame);
265 } 272 }
266 273
267 if (m_allDataReceived) { 274 if (m_allDataReceived) {
268 m_repetitionCount = m_actualDecoder->repetitionCount(); 275 m_repetitionCount = m_actualDecoder->repetitionCount();
269 m_actualDecoder.clear(); 276 m_actualDecoder.clear();
270 m_data = nullptr; 277 // Hold on to m_rwBuffer, which is still needed by createFrameAtIndex.
271 } 278 }
272 } 279 }
273 280
274 inline SkImageInfo imageInfoFrom(const SkISize& decodedSize, bool knownToBeOpaqu e) 281 inline SkImageInfo imageInfoFrom(const SkISize& decodedSize, bool knownToBeOpaqu e)
275 { 282 {
276 return SkImageInfo::MakeN32(decodedSize.width(), decodedSize.height(), known ToBeOpaque ? kOpaque_SkAlphaType : kPremul_SkAlphaType); 283 return SkImageInfo::MakeN32(decodedSize.width(), decodedSize.height(), known ToBeOpaque ? kOpaque_SkAlphaType : kPremul_SkAlphaType);
277 } 284 }
278 285
279 PassRefPtr<SkImage> DeferredImageDecoder::createFrameImageAtIndex(size_t index, bool knownToBeOpaque) const 286 PassRefPtr<SkImage> DeferredImageDecoder::createFrameImageAtIndex(size_t index, bool knownToBeOpaque) const
280 { 287 {
281 const SkISize& decodedSize = m_frameGenerator->getFullSize(); 288 const SkISize& decodedSize = m_frameGenerator->getFullSize();
282 ASSERT(decodedSize.width() > 0); 289 ASSERT(decodedSize.width() > 0);
283 ASSERT(decodedSize.height() > 0); 290 ASSERT(decodedSize.height() > 0);
284 291
285 DecodingImageGenerator* generator = new DecodingImageGenerator(m_frameGenera tor, imageInfoFrom(decodedSize, knownToBeOpaque), index); 292 RefPtr<SkROBuffer> roBuffer = adoptRef(m_rwBuffer->newRBufferSnapshot());
293 RefPtr<SegmentReader> segmentReader = SegmentReader::createFromSkROBuffer(ro Buffer.release());
294 DecodingImageGenerator* generator = new DecodingImageGenerator(m_frameGenera tor, imageInfoFrom(decodedSize, knownToBeOpaque), segmentReader.release(), m_all DataReceived, index);
286 RefPtr<SkImage> image = adoptRef(SkImage::NewFromGenerator(generator)); // S kImage takes ownership of the generator. 295 RefPtr<SkImage> image = adoptRef(SkImage::NewFromGenerator(generator)); // S kImage takes ownership of the generator.
287 if (!image) 296 if (!image)
288 return nullptr; 297 return nullptr;
289 298
290 generator->setCanYUVDecode(m_canYUVDecode); 299 generator->setCanYUVDecode(m_canYUVDecode);
291 300
292 return image.release(); 301 return image.release();
293 } 302 }
294 303
295 bool DeferredImageDecoder::hotSpot(IntPoint& hotSpot) const 304 bool DeferredImageDecoder::hotSpot(IntPoint& hotSpot) const
296 { 305 {
297 // TODO: Implement. 306 // TODO: Implement.
298 return m_actualDecoder ? m_actualDecoder->hotSpot(hotSpot) : false; 307 return m_actualDecoder ? m_actualDecoder->hotSpot(hotSpot) : false;
299 } 308 }
300 309
301 } // namespace blink 310 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698