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

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

Issue 985583002: Don't cache any SkBitmaps in DeferredImageDecoder (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: done now Created 5 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 | Annotate | Revision Log
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
(...skipping 27 matching lines...) Expand all
38 // URI label for SkDiscardablePixelRef. 38 // URI label for SkDiscardablePixelRef.
39 const char labelDiscardable[] = "discardable"; 39 const char labelDiscardable[] = "discardable";
40 40
41 } // namespace 41 } // namespace
42 42
43 bool DeferredImageDecoder::s_enabled = false; 43 bool DeferredImageDecoder::s_enabled = false;
44 44
45 DeferredImageDecoder::DeferredImageDecoder(PassOwnPtr<ImageDecoder> actualDecode r) 45 DeferredImageDecoder::DeferredImageDecoder(PassOwnPtr<ImageDecoder> actualDecode r)
46 : m_allDataReceived(false) 46 : m_allDataReceived(false)
47 , m_lastDataSize(0) 47 , m_lastDataSize(0)
48 , m_dataChanged(false)
49 , m_actualDecoder(actualDecoder) 48 , m_actualDecoder(actualDecoder)
50 , m_orientation(DefaultImageOrientation)
51 , m_repetitionCount(cAnimationNone) 49 , m_repetitionCount(cAnimationNone)
52 , m_hasColorProfile(false) 50 , m_hasColorProfile(false)
53 { 51 {
54 } 52 }
55 53
56 DeferredImageDecoder::~DeferredImageDecoder() 54 DeferredImageDecoder::~DeferredImageDecoder()
57 { 55 {
58 } 56 }
59 57
60 PassOwnPtr<DeferredImageDecoder> DeferredImageDecoder::create(const SharedBuffer & data, ImageSource::AlphaOption alphaOption, ImageSource::GammaAndColorProfileO ption gammaAndColorOption) 58 PassOwnPtr<DeferredImageDecoder> DeferredImageDecoder::create(const SharedBuffer & data, ImageSource::AlphaOption alphaOption, ImageSource::GammaAndColorProfileO ption gammaAndColorOption)
(...skipping 22 matching lines...) Expand all
83 bool DeferredImageDecoder::enabled() 81 bool DeferredImageDecoder::enabled()
84 { 82 {
85 return s_enabled; 83 return s_enabled;
86 } 84 }
87 85
88 String DeferredImageDecoder::filenameExtension() const 86 String DeferredImageDecoder::filenameExtension() const
89 { 87 {
90 return m_actualDecoder ? m_actualDecoder->filenameExtension() : m_filenameEx tension; 88 return m_actualDecoder ? m_actualDecoder->filenameExtension() : m_filenameEx tension;
91 } 89 }
92 90
93 ImageFrame* DeferredImageDecoder::frameBufferAtIndex(size_t index) 91 PassRefPtr<NativeImageSkia> DeferredImageDecoder::createFrameAtIndex(size_t inde x)
94 { 92 {
95 prepareLazyDecodedFrames(); 93 prepareLazyDecodedFrames();
96 if (index < m_lazyDecodedFrames.size()) { 94 if (index < m_frameData.size()) {
97 // ImageFrameGenerator has the latest known alpha state. There will 95 // ImageFrameGenerator has the latest known alpha state. There will
98 // be a performance boost if this frame is opaque. 96 // be a performance boost if this frame is opaque.
99 m_lazyDecodedFrames[index]->setHasAlpha(m_frameGenerator->hasAlpha(index )); 97 SkBitmap bitmap = createBitmap(index);
100 return m_lazyDecodedFrames[index].get(); 98 if (m_frameGenerator->hasAlpha(index)) {
99 m_frameData[index].m_hasAlpha = true;
100 bitmap.setAlphaType(kPremul_SkAlphaType);
101 } else {
102 m_frameData[index].m_hasAlpha = false;
103 bitmap.setAlphaType(kOpaque_SkAlphaType);
104 }
105 m_frameData[index].m_frameBytes = m_size.area() * sizeof(ImageFrame::Pi xelData);
106 return NativeImageSkia::create(bitmap);
101 } 107 }
102 if (m_actualDecoder) 108 if (m_actualDecoder) {
103 return m_actualDecoder->frameBufferAtIndex(index); 109 ImageFrame* buffer = m_actualDecoder->frameBufferAtIndex(index);
104 return 0; 110 if (!buffer || buffer->status() == ImageFrame::FrameEmpty)
111 return nullptr;
112 return buffer->asNewNativeImage();
113 }
114 return nullptr;
105 } 115 }
106 116
107 void DeferredImageDecoder::setData(SharedBuffer& data, bool allDataReceived) 117 void DeferredImageDecoder::setData(SharedBuffer& data, bool allDataReceived)
108 { 118 {
109 if (m_actualDecoder) { 119 if (m_actualDecoder) {
110 const bool firstData = !m_data;
111 const bool moreData = data.size() > m_lastDataSize;
112 m_dataChanged = firstData || moreData;
113 m_data = RefPtr<SharedBuffer>(data); 120 m_data = RefPtr<SharedBuffer>(data);
114 m_lastDataSize = data.size(); 121 m_lastDataSize = data.size();
115 m_allDataReceived = allDataReceived; 122 m_allDataReceived = allDataReceived;
116 m_actualDecoder->setData(&data, allDataReceived); 123 m_actualDecoder->setData(&data, allDataReceived);
117 prepareLazyDecodedFrames(); 124 prepareLazyDecodedFrames();
118 } 125 }
119 126
120 if (m_frameGenerator) 127 if (m_frameGenerator)
121 m_frameGenerator->setData(&data, allDataReceived); 128 m_frameGenerator->setData(&data, allDataReceived);
122 } 129 }
(...skipping 17 matching lines...) Expand all
140 147
141 IntSize DeferredImageDecoder::frameSizeAtIndex(size_t index) const 148 IntSize DeferredImageDecoder::frameSizeAtIndex(size_t index) const
142 { 149 {
143 // FIXME: LocalFrame size is assumed to be uniform. This might not be true f or 150 // FIXME: LocalFrame size is assumed to be uniform. This might not be true f or
144 // future supported codecs. 151 // future supported codecs.
145 return m_actualDecoder ? m_actualDecoder->frameSizeAtIndex(index) : m_size; 152 return m_actualDecoder ? m_actualDecoder->frameSizeAtIndex(index) : m_size;
146 } 153 }
147 154
148 size_t DeferredImageDecoder::frameCount() 155 size_t DeferredImageDecoder::frameCount()
149 { 156 {
150 return m_actualDecoder ? m_actualDecoder->frameCount() : m_lazyDecodedFrames .size(); 157 return m_actualDecoder ? m_actualDecoder->frameCount() : m_frameData.size();
151 } 158 }
152 159
153 int DeferredImageDecoder::repetitionCount() const 160 int DeferredImageDecoder::repetitionCount() const
154 { 161 {
155 return m_actualDecoder ? m_actualDecoder->repetitionCount() : m_repetitionCo unt; 162 return m_actualDecoder ? m_actualDecoder->repetitionCount() : m_repetitionCo unt;
156 } 163 }
157 164
158 size_t DeferredImageDecoder::clearCacheExceptFrame(size_t clearExceptFrame) 165 size_t DeferredImageDecoder::clearCacheExceptFrame(size_t clearExceptFrame)
159 { 166 {
160 // If image decoding is deferred then frame buffer cache is managed by 167 if (m_actualDecoder)
161 // the compositor and this call is ignored. 168 return m_actualDecoder->clearCacheExceptFrame(clearExceptFrame);
162 return m_actualDecoder ? m_actualDecoder->clearCacheExceptFrame(clearExceptF rame) : 0; 169 size_t frameBytesCleared = 0;
170 for (size_t i = 0; i < m_frameData.size(); ++i) {
171 if (i != clearExceptFrame) {
172 frameBytesCleared += m_frameData[i].m_frameBytes;
173 m_frameData[i].m_frameBytes = 0;
174 }
175 }
176 return frameBytesCleared;
163 } 177 }
164 178
165 bool DeferredImageDecoder::frameHasAlphaAtIndex(size_t index) const 179 bool DeferredImageDecoder::frameHasAlphaAtIndex(size_t index) const
166 { 180 {
167 if (m_actualDecoder) 181 if (m_actualDecoder)
168 return m_actualDecoder->frameHasAlphaAtIndex(index); 182 return m_actualDecoder->frameHasAlphaAtIndex(index);
169 if (!m_frameGenerator->isMultiFrame()) 183 if (!m_frameGenerator->isMultiFrame())
170 return m_frameGenerator->hasAlpha(index); 184 return m_frameGenerator->hasAlpha(index);
171 return true; 185 return true;
172 } 186 }
173 187
174 bool DeferredImageDecoder::frameIsCompleteAtIndex(size_t index) const 188 bool DeferredImageDecoder::frameIsCompleteAtIndex(size_t index) const
175 { 189 {
176 if (m_actualDecoder) 190 if (m_actualDecoder)
177 return m_actualDecoder->frameIsCompleteAtIndex(index); 191 return m_actualDecoder->frameIsCompleteAtIndex(index);
178 if (index < m_lazyDecodedFrames.size()) 192 if (index < m_frameData.size())
179 return m_lazyDecodedFrames[index]->status() == ImageFrame::FrameComplete ; 193 return m_frameData[index].m_isComplete;
180 return false; 194 return false;
181 } 195 }
182 196
183 float DeferredImageDecoder::frameDurationAtIndex(size_t index) const 197 float DeferredImageDecoder::frameDurationAtIndex(size_t index) const
184 { 198 {
185 if (m_actualDecoder) 199 if (m_actualDecoder)
186 return m_actualDecoder->frameDurationAtIndex(index); 200 return m_actualDecoder->frameDurationAtIndex(index);
187 if (index < m_lazyDecodedFrames.size()) 201 if (index < m_frameData.size())
188 return m_lazyDecodedFrames[index]->duration(); 202 return m_frameData[index].m_duration;
189 return 0; 203 return 0;
190 } 204 }
191 205
192 unsigned DeferredImageDecoder::frameBytesAtIndex(size_t index) const 206 unsigned DeferredImageDecoder::frameBytesAtIndex(size_t index) const
193 { 207 {
194 // If frame decoding is deferred then it is not managed by MemoryCache 208 if (m_actualDecoder)
195 // so return 0 here. 209 return m_actualDecoder->frameBytesAtIndex(index);
196 return m_frameGenerator ? 0 : m_actualDecoder->frameBytesAtIndex(index); 210 if (index < m_frameData.size())
211 return m_frameData[index].m_frameBytes;
212 return 0;
197 } 213 }
198 214
199 ImageOrientation DeferredImageDecoder::orientation() const 215 ImageOrientation DeferredImageDecoder::orientationAtIndex(size_t index) const
200 { 216 {
201 return m_actualDecoder ? m_actualDecoder->orientation() : m_orientation; 217 if (m_actualDecoder)
218 return m_actualDecoder->orientation();
219 if (index < m_frameData.size())
220 return m_frameData[index].m_orientation;
221 return DefaultImageOrientation;
202 } 222 }
203 223
204 void DeferredImageDecoder::activateLazyDecoding() 224 void DeferredImageDecoder::activateLazyDecoding()
205 { 225 {
206 if (m_frameGenerator) 226 if (m_frameGenerator)
207 return; 227 return;
208 m_size = m_actualDecoder->size(); 228 m_size = m_actualDecoder->size();
209 m_orientation = m_actualDecoder->orientation();
210 m_filenameExtension = m_actualDecoder->filenameExtension(); 229 m_filenameExtension = m_actualDecoder->filenameExtension();
211 m_hasColorProfile = m_actualDecoder->hasColorProfile(); 230 m_hasColorProfile = m_actualDecoder->hasColorProfile();
212 const bool isSingleFrame = m_actualDecoder->repetitionCount() == cAnimationN one || (m_allDataReceived && m_actualDecoder->frameCount() == 1u); 231 const bool isSingleFrame = m_actualDecoder->repetitionCount() == cAnimationN one || (m_allDataReceived && m_actualDecoder->frameCount() == 1u);
213 m_frameGenerator = ImageFrameGenerator::create(SkISize::Make(m_actualDecoder ->decodedSize().width(), m_actualDecoder->decodedSize().height()), m_data, m_all DataReceived, !isSingleFrame); 232 m_frameGenerator = ImageFrameGenerator::create(SkISize::Make(m_actualDecoder ->decodedSize().width(), m_actualDecoder->decodedSize().height()), m_data, m_all DataReceived, !isSingleFrame);
214 } 233 }
215 234
216 void DeferredImageDecoder::prepareLazyDecodedFrames() 235 void DeferredImageDecoder::prepareLazyDecodedFrames()
217 { 236 {
218 if (!s_enabled 237 if (!s_enabled
219 || !m_actualDecoder 238 || !m_actualDecoder
220 || !m_actualDecoder->isSizeAvailable() 239 || !m_actualDecoder->isSizeAvailable()
221 || m_actualDecoder->filenameExtension() == "ico") 240 || m_actualDecoder->filenameExtension() == "ico")
222 return; 241 return;
223 242
224 activateLazyDecoding(); 243 activateLazyDecoding();
225 244
226 const size_t previousSize = m_lazyDecodedFrames.size(); 245 const size_t previousSize = m_frameData.size();
227 m_lazyDecodedFrames.resize(m_actualDecoder->frameCount()); 246 m_frameData.resize(m_actualDecoder->frameCount());
228 247
229 // We have encountered a broken image file. Simply bail. 248 // We have encountered a broken image file. Simply bail.
230 if (m_lazyDecodedFrames.size() < previousSize) 249 if (m_frameData.size() < previousSize)
231 return; 250 return;
232 251
233 for (size_t i = previousSize; i < m_lazyDecodedFrames.size(); ++i) { 252 for (size_t i = previousSize; i < m_frameData.size(); ++i) {
234 OwnPtr<ImageFrame> frame(adoptPtr(new ImageFrame())); 253 OwnPtr<ImageFrame> frame(adoptPtr(new ImageFrame()));
235 frame->setSkBitmap(createBitmap(i)); 254 m_frameData[i].m_haveMetadata = true;
236 frame->setDuration(m_actualDecoder->frameDurationAtIndex(i)); 255 m_frameData[i].m_duration = m_actualDecoder->frameDurationAtIndex(i);
237 frame->setStatus(m_actualDecoder->frameIsCompleteAtIndex(i) ? ImageFrame ::FrameComplete : ImageFrame::FramePartial); 256 m_frameData[i].m_orientation = m_actualDecoder->orientation();
238 m_lazyDecodedFrames[i] = frame.release(); 257 m_frameData[i].m_isComplete = m_actualDecoder->frameIsCompleteAtIndex(i) ;
239 } 258 }
240 259
241 // The last lazy decoded frame created from previous call might be 260 // The last lazy decoded frame created from previous call might be
242 // incomplete so update its state. 261 // incomplete so update its state.
243 if (previousSize) { 262 if (previousSize) {
244 const size_t lastFrame = previousSize - 1; 263 const size_t lastFrame = previousSize - 1;
245 m_lazyDecodedFrames[lastFrame]->setStatus(m_actualDecoder->frameIsComple teAtIndex(lastFrame) ? ImageFrame::FrameComplete : ImageFrame::FramePartial); 264 m_frameData[lastFrame].m_isComplete = m_actualDecoder->frameIsCompleteAt Index(lastFrame);
246
247 // If data has changed then create a new bitmap. This forces
248 // Skia to decode again.
249 if (m_dataChanged) {
250 m_dataChanged = false;
251 m_lazyDecodedFrames[lastFrame]->setSkBitmap(createBitmap(lastFrame)) ;
252 }
253 } 265 }
254 266
255 if (m_allDataReceived) { 267 if (m_allDataReceived) {
256 m_repetitionCount = m_actualDecoder->repetitionCount(); 268 m_repetitionCount = m_actualDecoder->repetitionCount();
257 m_actualDecoder.clear(); 269 m_actualDecoder.clear();
258 m_data = nullptr; 270 m_data = nullptr;
259 } 271 }
260 } 272 }
261 273
262 // Creates a SkBitmap that is backed by SkDiscardablePixelRef. 274 // Creates a SkBitmap that is backed by SkDiscardablePixelRef.
263 SkBitmap DeferredImageDecoder::createBitmap(size_t index) 275 SkBitmap DeferredImageDecoder::createBitmap(size_t index)
264 { 276 {
265 IntSize decodedSize = m_actualDecoder->decodedSize(); 277 SkISize decodedSize = m_frameGenerator->getFullSize();
266 ASSERT(decodedSize.width() > 0); 278 ASSERT(decodedSize.width() > 0);
267 ASSERT(decodedSize.height() > 0); 279 ASSERT(decodedSize.height() > 0);
268 280
269 #if SK_B32_SHIFT // Little-endian RGBA pixels. (Android) 281 #if SK_B32_SHIFT // Little-endian RGBA pixels. (Android)
270 const SkColorType colorType = kRGBA_8888_SkColorType; 282 const SkColorType colorType = kRGBA_8888_SkColorType;
271 #else 283 #else
272 const SkColorType colorType = kBGRA_8888_SkColorType; 284 const SkColorType colorType = kBGRA_8888_SkColorType;
273 #endif 285 #endif
274 const SkImageInfo info = SkImageInfo::Make(decodedSize.width(), decodedSize. height(), colorType, kPremul_SkAlphaType); 286 const SkImageInfo info = SkImageInfo::Make(decodedSize.width(), decodedSize. height(), colorType, kPremul_SkAlphaType);
275 287
276 SkBitmap bitmap; 288 SkBitmap bitmap;
277 DecodingImageGenerator* generator = new DecodingImageGenerator(m_frameGenera tor, info, index); 289 DecodingImageGenerator* generator = new DecodingImageGenerator(m_frameGenera tor, info, index);
278 bool installed = SkInstallDiscardablePixelRef(generator, &bitmap); 290 bool installed = SkInstallDiscardablePixelRef(generator, &bitmap);
279 ASSERT_UNUSED(installed, installed); 291 ASSERT_UNUSED(installed, installed);
280 bitmap.pixelRef()->setURI(labelDiscardable); 292 bitmap.pixelRef()->setURI(labelDiscardable);
281 generator->setGenerationId(bitmap.getGenerationID()); 293 generator->setGenerationId(bitmap.getGenerationID());
282 return bitmap; 294 return bitmap;
283 } 295 }
284 296
285 bool DeferredImageDecoder::hotSpot(IntPoint& hotSpot) const 297 bool DeferredImageDecoder::hotSpot(IntPoint& hotSpot) const
286 { 298 {
287 // TODO: Implement. 299 // TODO: Implement.
288 return m_actualDecoder ? m_actualDecoder->hotSpot(hotSpot) : false; 300 return m_actualDecoder ? m_actualDecoder->hotSpot(hotSpot) : false;
289 } 301 }
290 302
291 } // namespace blink 303 } // namespace blink
OLDNEW
« no previous file with comments | « Source/platform/graphics/DeferredImageDecoder.h ('k') | Source/platform/graphics/DeferredImageDecoderTest.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698