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

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: 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/ROBufferSegmentReader.h"
35 #include "platform/image-decoders/SharedBufferSegmentReader.h"
36 #include "skia/ext/refptr.h"
33 #include "third_party/skia/include/core/SkImage.h" 37 #include "third_party/skia/include/core/SkImage.h"
34 #include "wtf/PassOwnPtr.h" 38 #include "wtf/PassOwnPtr.h"
35 39
36 namespace blink { 40 namespace blink {
37 41
38 bool DeferredImageDecoder::s_enabled = true; 42 bool DeferredImageDecoder::s_enabled = true;
39 43
40 PassOwnPtr<DeferredImageDecoder> DeferredImageDecoder::create(const SharedBuffer & data, ImageDecoder::AlphaOption alphaOption, ImageDecoder::GammaAndColorProfil eOption colorOptions) 44 PassOwnPtr<DeferredImageDecoder> DeferredImageDecoder::create(const SharedBuffer & data, ImageDecoder::AlphaOption alphaOption, ImageDecoder::GammaAndColorProfil eOption colorOptions)
41 { 45 {
42 OwnPtr<ImageDecoder> actualDecoder = ImageDecoder::create(data, alphaOption, colorOptions); 46 // FIXME: This const_cast is necessary because the SharedBufferSegmentReader expects a non-const, but
47 // it does not modify it.
f(malita) 2016/03/23 16:41:57 Since SharedBufferSegmentReader only calls const S
scroggo_chromium 2016/03/24 13:59:44 I don't think so. ref() and deref() are not marked
48 RefPtr<SegmentReader> segmentReader = adoptRef(new SharedBufferSegmentReader (const_cast<SharedBuffer*>(&data)));
49 OwnPtr<ImageDecoder> actualDecoder = ImageDecoder::create(*segmentReader.get (), alphaOption, colorOptions);
43 50
44 if (!actualDecoder) 51 if (!actualDecoder)
45 return nullptr; 52 return nullptr;
46 53
47 return adoptPtr(new DeferredImageDecoder(actualDecoder.release())); 54 return adoptPtr(new DeferredImageDecoder(actualDecoder.release()));
48 } 55 }
49 56
50 PassOwnPtr<DeferredImageDecoder> DeferredImageDecoder::createForTesting(PassOwnP tr<ImageDecoder> actualDecoder) 57 PassOwnPtr<DeferredImageDecoder> DeferredImageDecoder::createForTesting(PassOwnP tr<ImageDecoder> actualDecoder)
51 { 58 {
52 return adoptPtr(new DeferredImageDecoder(std::move(actualDecoder))); 59 return adoptPtr(new DeferredImageDecoder(std::move(actualDecoder)));
53 } 60 }
54 61
55 DeferredImageDecoder::DeferredImageDecoder(PassOwnPtr<ImageDecoder> actualDecode r) 62 DeferredImageDecoder::DeferredImageDecoder(PassOwnPtr<ImageDecoder> actualDecode r)
56 : m_allDataReceived(false) 63 : m_allDataReceived(false)
57 , m_lastDataSize(0)
58 , m_actualDecoder(std::move(actualDecoder)) 64 , m_actualDecoder(std::move(actualDecoder))
59 , m_repetitionCount(cAnimationNone) 65 , m_repetitionCount(cAnimationNone)
60 , m_hasColorProfile(false) 66 , m_hasColorProfile(false)
61 , m_canYUVDecode(false) 67 , m_canYUVDecode(false)
62 { 68 {
63 } 69 }
64 70
65 DeferredImageDecoder::~DeferredImageDecoder() 71 DeferredImageDecoder::~DeferredImageDecoder()
66 { 72 {
67 } 73 }
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
104 ImageFrame* frame = m_actualDecoder->frameBufferAtIndex(index); 110 ImageFrame* frame = m_actualDecoder->frameBufferAtIndex(index);
105 if (!frame || frame->status() == ImageFrame::FrameEmpty) 111 if (!frame || frame->status() == ImageFrame::FrameEmpty)
106 return nullptr; 112 return nullptr;
107 113
108 return adoptRef(SkImage::NewFromBitmap(frame->bitmap())); 114 return adoptRef(SkImage::NewFromBitmap(frame->bitmap()));
109 } 115 }
110 116
111 void DeferredImageDecoder::setData(SharedBuffer& data, bool allDataReceived) 117 void DeferredImageDecoder::setData(SharedBuffer& data, bool allDataReceived)
112 { 118 {
113 if (m_actualDecoder) { 119 if (m_actualDecoder) {
114 m_data = RefPtr<SharedBuffer>(data); 120 RefPtr<SegmentReader> segmentReader = adoptRef(new SharedBufferSegmentRe ader(RefPtr<SharedBuffer>(data)));
Peter Kasting 2016/03/23 02:42:58 Nit: Move down one line
scroggo_chromium 2016/03/24 13:59:44 Done.
115 m_lastDataSize = data.size();
116 m_allDataReceived = allDataReceived; 121 m_allDataReceived = allDataReceived;
117 m_actualDecoder->setData(&data, allDataReceived); 122 m_actualDecoder->setData(segmentReader.get(), allDataReceived);
Peter Kasting 2016/03/23 02:42:58 This pattern (create a local SharedBufferSegmentRe
scroggo_chromium 2016/03/24 13:59:44 Agreed. Done.
118 prepareLazyDecodedFrames(); 123 prepareLazyDecodedFrames();
119 } 124 }
120 125
121 if (m_frameGenerator) 126 if (m_frameGenerator) {
122 m_frameGenerator->setData(&data, allDataReceived); 127 if (!m_rwBuffer) {
Peter Kasting 2016/03/23 02:42:58 Nit: No {} (anywhere we have a one-line body)
scroggo_chromium 2016/03/24 13:59:44 Done.
128 m_rwBuffer = adoptPtr(new SkRWBuffer(data.size()));
129 }
130
131 const char* segment = 0;
132 while (size_t length = data.getSomeData(segment, m_rwBuffer->size())) {
scroggo_chromium 2016/03/22 20:18:41 This copy is analogous to the code in ThreadSafeDa
133 m_rwBuffer->append(segment, length);
134 }
135 }
123 } 136 }
124 137
125 bool DeferredImageDecoder::isSizeAvailable() 138 bool DeferredImageDecoder::isSizeAvailable()
126 { 139 {
127 // m_actualDecoder is 0 only if image decoding is deferred and that means 140 // m_actualDecoder is 0 only if image decoding is deferred and that means
128 // the image header decoded successfully and the size is available. 141 // the image header decoded successfully and the size is available.
129 return m_actualDecoder ? m_actualDecoder->isSizeAvailable() : true; 142 return m_actualDecoder ? m_actualDecoder->isSizeAvailable() : true;
130 } 143 }
131 144
132 bool DeferredImageDecoder::hasColorProfile() const 145 bool DeferredImageDecoder::hasColorProfile() const
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
220 if (m_frameGenerator) 233 if (m_frameGenerator)
221 return; 234 return;
222 235
223 m_size = m_actualDecoder->size(); 236 m_size = m_actualDecoder->size();
224 m_filenameExtension = m_actualDecoder->filenameExtension(); 237 m_filenameExtension = m_actualDecoder->filenameExtension();
225 // JPEG images support YUV decoding: other decoders do not, WEBP could in fu ture. 238 // JPEG images support YUV decoding: other decoders do not, WEBP could in fu ture.
226 m_canYUVDecode = RuntimeEnabledFeatures::decodeToYUVEnabled() && (m_filename Extension == "jpg"); 239 m_canYUVDecode = RuntimeEnabledFeatures::decodeToYUVEnabled() && (m_filename Extension == "jpg");
227 m_hasColorProfile = m_actualDecoder->hasColorProfile(); 240 m_hasColorProfile = m_actualDecoder->hasColorProfile();
228 241
229 const bool isSingleFrame = m_actualDecoder->repetitionCount() == cAnimationN one || (m_allDataReceived && m_actualDecoder->frameCount() == 1u); 242 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); 243 m_frameGenerator = ImageFrameGenerator::create(SkISize::Make(m_actualDecoder ->decodedSize().width(), m_actualDecoder->decodedSize().height()),
Peter Kasting 2016/03/23 02:42:58 Nit: Either put everything on one line, or linebre
scroggo_chromium 2016/03/24 13:59:44 I created a temporary variable, as is done with is
244 !isSingleFrame);
231 } 245 }
232 246
233 void DeferredImageDecoder::prepareLazyDecodedFrames() 247 void DeferredImageDecoder::prepareLazyDecodedFrames()
234 { 248 {
235 if (!s_enabled 249 if (!s_enabled
236 || !m_actualDecoder 250 || !m_actualDecoder
237 || !m_actualDecoder->isSizeAvailable() 251 || !m_actualDecoder->isSizeAvailable()
238 || m_actualDecoder->filenameExtension() == "ico") 252 || m_actualDecoder->filenameExtension() == "ico")
239 return; 253 return;
240 254
(...skipping 15 matching lines...) Expand all
256 270
257 // The last lazy decoded frame created from previous call might be 271 // The last lazy decoded frame created from previous call might be
258 // incomplete so update its state. 272 // incomplete so update its state.
259 if (previousSize) { 273 if (previousSize) {
260 const size_t lastFrame = previousSize - 1; 274 const size_t lastFrame = previousSize - 1;
261 m_frameData[lastFrame].m_isComplete = m_actualDecoder->frameIsCompleteAt Index(lastFrame); 275 m_frameData[lastFrame].m_isComplete = m_actualDecoder->frameIsCompleteAt Index(lastFrame);
262 } 276 }
263 277
264 if (m_allDataReceived) { 278 if (m_allDataReceived) {
265 m_repetitionCount = m_actualDecoder->repetitionCount(); 279 m_repetitionCount = m_actualDecoder->repetitionCount();
266 m_actualDecoder.clear(); 280 m_actualDecoder.clear();
scroggo_chromium 2016/03/22 20:18:42 We hang on to the SkRWBuffer here, unlike the old
Peter Kasting 2016/03/23 02:42:58 Might want to write a comment about that.
scroggo_chromium 2016/03/24 13:59:45 Done.
267 m_data = nullptr;
268 } 281 }
269 } 282 }
270 283
271 inline SkImageInfo imageInfoFrom(const SkISize& decodedSize, bool knownToBeOpaqu e) 284 inline SkImageInfo imageInfoFrom(const SkISize& decodedSize, bool knownToBeOpaqu e)
272 { 285 {
273 return SkImageInfo::MakeN32(decodedSize.width(), decodedSize.height(), known ToBeOpaque ? kOpaque_SkAlphaType : kPremul_SkAlphaType); 286 return SkImageInfo::MakeN32(decodedSize.width(), decodedSize.height(), known ToBeOpaque ? kOpaque_SkAlphaType : kPremul_SkAlphaType);
274 } 287 }
275 288
276 PassRefPtr<SkImage> DeferredImageDecoder::createFrameImageAtIndex(size_t index, bool knownToBeOpaque) const 289 PassRefPtr<SkImage> DeferredImageDecoder::createFrameImageAtIndex(size_t index, bool knownToBeOpaque) const
277 { 290 {
278 const SkISize& decodedSize = m_frameGenerator->getFullSize(); 291 const SkISize& decodedSize = m_frameGenerator->getFullSize();
279 ASSERT(decodedSize.width() > 0); 292 ASSERT(decodedSize.width() > 0);
280 ASSERT(decodedSize.height() > 0); 293 ASSERT(decodedSize.height() > 0);
281 294
282 DecodingImageGenerator* generator = new DecodingImageGenerator(m_frameGenera tor, imageInfoFrom(decodedSize, knownToBeOpaque), index); 295 skia::RefPtr<SkROBuffer> roBuffer = skia::AdoptRef(m_rwBuffer->newRBufferSna pshot());
scroggo_chromium 2016/03/22 20:18:42 Some of the Blink code that uses a Skia object wra
Peter Kasting 2016/03/23 02:42:58 Use skia::RefPtr for now, I think.
f(malita) 2016/03/23 16:41:58 skia::RefPtr is only used in Chromium code AFAIK.
scroggo_chromium 2016/03/24 13:59:44 Yes, it does appear skia::RefPtr is only used in C
296 RefPtr<SegmentReader> segmentReader = adoptRef(new ROBufferSegmentReader(roB uffer));
297 DecodingImageGenerator* generator = new DecodingImageGenerator(m_frameGenera tor, imageInfoFrom(decodedSize, knownToBeOpaque), segmentReader, m_allDataReceiv ed, index);
283 RefPtr<SkImage> image = adoptRef(SkImage::NewFromGenerator(generator)); // S kImage takes ownership of the generator. 298 RefPtr<SkImage> image = adoptRef(SkImage::NewFromGenerator(generator)); // S kImage takes ownership of the generator.
284 if (!image) 299 if (!image)
285 return nullptr; 300 return nullptr;
286 301
287 generator->setGenerationId(image->uniqueID()); 302 generator->setGenerationId(image->uniqueID());
288 generator->setCanYUVDecode(m_canYUVDecode); 303 generator->setCanYUVDecode(m_canYUVDecode);
289 304
290 return image.release(); 305 return image.release();
291 } 306 }
292 307
293 bool DeferredImageDecoder::hotSpot(IntPoint& hotSpot) const 308 bool DeferredImageDecoder::hotSpot(IntPoint& hotSpot) const
294 { 309 {
295 // TODO: Implement. 310 // TODO: Implement.
296 return m_actualDecoder ? m_actualDecoder->hotSpot(hotSpot) : false; 311 return m_actualDecoder ? m_actualDecoder->hotSpot(hotSpot) : false;
297 } 312 }
298 313
299 } // namespace blink 314 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698