OLD | NEW |
1 /* | 1 /* |
2 Copyright (C) 1998 Lars Knoll (knoll@mpi-hd.mpg.de) | 2 Copyright (C) 1998 Lars Knoll (knoll@mpi-hd.mpg.de) |
3 Copyright (C) 2001 Dirk Mueller (mueller@kde.org) | 3 Copyright (C) 2001 Dirk Mueller (mueller@kde.org) |
4 Copyright (C) 2002 Waldo Bastian (bastian@kde.org) | 4 Copyright (C) 2002 Waldo Bastian (bastian@kde.org) |
5 Copyright (C) 2006 Samuel Weinig (sam.weinig@gmail.com) | 5 Copyright (C) 2006 Samuel Weinig (sam.weinig@gmail.com) |
6 Copyright (C) 2004, 2005, 2006, 2007 Apple Inc. All rights reserved. | 6 Copyright (C) 2004, 2005, 2006, 2007 Apple Inc. All rights reserved. |
7 | 7 |
8 This library is free software; you can redistribute it and/or | 8 This library is free software; you can redistribute it and/or |
9 modify it under the terms of the GNU Library General Public | 9 modify it under the terms of the GNU Library General Public |
10 License as published by the Free Software Foundation; either | 10 License as published by the Free Software Foundation; either |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
110 HashCountedSet<ImageResourceObserver*> observers; | 110 HashCountedSet<ImageResourceObserver*> observers; |
111 m_observers.swap(observers); | 111 m_observers.swap(observers); |
112 for (const auto& it : observers) | 112 for (const auto& it : observers) |
113 m_finishedObservers.add(it.key, it.value); | 113 m_finishedObservers.add(it.key, it.value); |
114 | 114 |
115 Resource::markClientsAndObserversFinished(); | 115 Resource::markClientsAndObserversFinished(); |
116 } | 116 } |
117 | 117 |
118 void ImageResource::didAddClient(ResourceClient* client) | 118 void ImageResource::didAddClient(ResourceClient* client) |
119 { | 119 { |
120 DCHECK((m_multipartParser && isLoading()) || !m_data || m_image); | 120 DCHECK((m_multipartParser && isLoading()) || !data() || m_image); |
121 Resource::didAddClient(client); | 121 Resource::didAddClient(client); |
122 } | 122 } |
123 | 123 |
124 void ImageResource::addObserver(ImageResourceObserver* observer) | 124 void ImageResource::addObserver(ImageResourceObserver* observer) |
125 { | 125 { |
126 willAddClientOrObserver(); | 126 willAddClientOrObserver(); |
127 | 127 |
128 m_observers.add(observer); | 128 m_observers.add(observer); |
129 | 129 |
130 if (isCacheValidator()) | 130 if (isCacheValidator()) |
131 return; | 131 return; |
132 | 132 |
133 // When the response is not multipart, if |m_data| exists, |m_image| must | 133 // When the response is not multipart, if |data()| exists, |m_image| must be |
134 // be created. This is assured that |updateImage()| is called when | 134 // created. This is assured that |updateImage()| is called when |
135 // |appendData()| is called. | 135 // |appendData()| is called. |
136 // | 136 // |
137 // On the other hand, when the response is multipart, |updateImage()| is | 137 // On the other hand, when the response is multipart, |updateImage()| is |
138 // not called in |appendData()|, which means |m_image| might not be created | 138 // not called in |appendData()|, which means |m_image| might not be created |
139 // even when |m_data| exists. This is intentional since creating a |m_image| | 139 // even when |data()| exists. This is intentional since creating a |m_image| |
140 // on receiving data might destroy an existing image in a previous part. | 140 // on receiving data might destroy an existing image in a previous part. |
141 DCHECK((m_multipartParser && isLoading()) || !m_data || m_image); | 141 DCHECK((m_multipartParser && isLoading()) || !data() || m_image); |
142 | 142 |
143 if (m_image && !m_image->isNull()) { | 143 if (m_image && !m_image->isNull()) { |
144 observer->imageChanged(this); | 144 observer->imageChanged(this); |
145 } | 145 } |
146 | 146 |
147 if (isLoaded()) { | 147 if (isLoaded()) { |
148 observer->imageNotifyFinished(this); | 148 observer->imageNotifyFinished(this); |
149 if (m_observers.contains(observer)) { | 149 if (m_observers.contains(observer)) { |
150 m_finishedObservers.add(observer); | 150 m_finishedObservers.add(observer); |
151 m_observers.remove(observer); | 151 m_observers.remove(observer); |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
188 ImageResourceObserverWalker walker(m_observers); | 188 ImageResourceObserverWalker walker(m_observers); |
189 while (const auto* observer = walker.next()) { | 189 while (const auto* observer = walker.next()) { |
190 priorityFromObserver(observer, priority); | 190 priorityFromObserver(observer, priority); |
191 } | 191 } |
192 | 192 |
193 return priority; | 193 return priority; |
194 } | 194 } |
195 | 195 |
196 bool ImageResource::isSafeToUnlock() const | 196 bool ImageResource::isSafeToUnlock() const |
197 { | 197 { |
198 // Note that |m_image| holds a reference to |m_data| in addition to the one
held by the Resource parent class. | 198 // Note that |m_image| holds a reference to |data()| in addition to the one
held by the Resource parent class. |
199 return !m_image || (m_image->hasOneRef() && m_data->refCount() == 2); | 199 return !m_image || (m_image->hasOneRef() && data()->refCount() == 2); |
200 } | 200 } |
201 | 201 |
202 void ImageResource::destroyDecodedDataForFailedRevalidation() | 202 void ImageResource::destroyDecodedDataForFailedRevalidation() |
203 { | 203 { |
204 clearImage(); | 204 clearImage(); |
205 setDecodedSize(0); | 205 setDecodedSize(0); |
206 } | 206 } |
207 | 207 |
208 void ImageResource::destroyDecodedDataIfPossible() | 208 void ImageResource::destroyDecodedDataIfPossible() |
209 { | 209 { |
(...skipping 21 matching lines...) Expand all Loading... |
231 else | 231 else |
232 m_image->resetAnimation(); | 232 m_image->resetAnimation(); |
233 } | 233 } |
234 if (m_multipartParser) | 234 if (m_multipartParser) |
235 m_multipartParser->cancel(); | 235 m_multipartParser->cancel(); |
236 Resource::allClientsAndObserversRemoved(); | 236 Resource::allClientsAndObserversRemoved(); |
237 } | 237 } |
238 | 238 |
239 PassRefPtr<SharedBuffer> ImageResource::resourceBuffer() const | 239 PassRefPtr<SharedBuffer> ImageResource::resourceBuffer() const |
240 { | 240 { |
241 if (m_data) | 241 if (data()) |
242 return m_data.get(); | 242 return data(); |
243 if (m_image) | 243 if (m_image) |
244 return m_image->data(); | 244 return m_image->data(); |
245 return nullptr; | 245 return nullptr; |
246 } | 246 } |
247 | 247 |
248 void ImageResource::appendData(const char* data, size_t length) | 248 void ImageResource::appendData(const char* data, size_t length) |
249 { | 249 { |
250 if (m_multipartParser) { | 250 if (m_multipartParser) { |
251 m_multipartParser->appendData(data, length); | 251 m_multipartParser->appendData(data, length); |
252 } else { | 252 } else { |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
341 | 341 |
342 ImageResourceObserverWalker walker(m_observers); | 342 ImageResourceObserverWalker walker(m_observers); |
343 while (auto* observer = walker.next()) { | 343 while (auto* observer = walker.next()) { |
344 observer->imageChanged(this, changeRect); | 344 observer->imageChanged(this, changeRect); |
345 } | 345 } |
346 } | 346 } |
347 | 347 |
348 void ImageResource::clear() | 348 void ImageResource::clear() |
349 { | 349 { |
350 clearImage(); | 350 clearImage(); |
351 m_data.clear(); | 351 clearData(); |
352 setEncodedSize(0); | 352 setEncodedSize(0); |
353 } | 353 } |
354 | 354 |
355 inline void ImageResource::createImage() | 355 inline void ImageResource::createImage() |
356 { | 356 { |
357 // Create the image if it doesn't yet exist. | 357 // Create the image if it doesn't yet exist. |
358 if (m_image) | 358 if (m_image) |
359 return; | 359 return; |
360 | 360 |
361 if (response().mimeType() == "image/svg+xml") { | 361 if (response().mimeType() == "image/svg+xml") { |
(...skipping 11 matching lines...) Expand all Loading... |
373 // If our Image has an observer, it's always us so we need to clear the back
pointer | 373 // If our Image has an observer, it's always us so we need to clear the back
pointer |
374 // before dropping our reference. | 374 // before dropping our reference. |
375 m_image->clearImageObserver(); | 375 m_image->clearImageObserver(); |
376 m_image.clear(); | 376 m_image.clear(); |
377 } | 377 } |
378 | 378 |
379 void ImageResource::updateImage(bool allDataReceived) | 379 void ImageResource::updateImage(bool allDataReceived) |
380 { | 380 { |
381 TRACE_EVENT0("blink", "ImageResource::updateImage"); | 381 TRACE_EVENT0("blink", "ImageResource::updateImage"); |
382 | 382 |
383 if (m_data) | 383 if (data()) |
384 createImage(); | 384 createImage(); |
385 | 385 |
386 Image::SizeAvailability sizeAvailable = Image::SizeUnavailable; | 386 Image::SizeAvailability sizeAvailable = Image::SizeUnavailable; |
387 | 387 |
388 // Have the image update its data from its internal buffer. | 388 // Have the image update its data from its internal buffer. |
389 // It will not do anything now, but will delay decoding until | 389 // It will not do anything now, but will delay decoding until |
390 // queried for info (like size or specific image frames). | 390 // queried for info (like size or specific image frames). |
391 if (m_data) { | 391 if (data()) { |
392 DCHECK(m_image); | 392 DCHECK(m_image); |
393 sizeAvailable = m_image->setData(m_data, allDataReceived); | 393 sizeAvailable = m_image->setData(data(), allDataReceived); |
394 } | 394 } |
395 | 395 |
396 // Go ahead and tell our observers to try to draw if we have either | 396 // Go ahead and tell our observers to try to draw if we have either |
397 // received all the data or the size is known. Each chunk from the | 397 // received all the data or the size is known. Each chunk from the |
398 // network causes observers to repaint, which will force that chunk | 398 // network causes observers to repaint, which will force that chunk |
399 // to decode. | 399 // to decode. |
400 if (sizeAvailable == Image::SizeUnavailable && !allDataReceived) | 400 if (sizeAvailable == Image::SizeUnavailable && !allDataReceived) |
401 return; | 401 return; |
402 if (!m_image || m_image->isNull()) { | 402 if (!m_image || m_image->isNull()) { |
403 if (!errorOccurred()) | 403 if (!errorOccurred()) |
404 setStatus(DecodeError); | 404 setStatus(DecodeError); |
405 if (!allDataReceived && loader()) | 405 if (!allDataReceived && loader()) |
406 loader()->didFinishLoading(nullptr, monotonicallyIncreasingTime(), e
ncodedSize()); | 406 loader()->didFinishLoading(nullptr, monotonicallyIncreasingTime(), e
ncodedSize()); |
407 clear(); | 407 clear(); |
408 memoryCache()->remove(this); | 408 memoryCache()->remove(this); |
409 } | 409 } |
410 | 410 |
411 // It would be nice to only redraw the decoded band of the image, but with t
he current design | 411 // It would be nice to only redraw the decoded band of the image, but with t
he current design |
412 // (decoding delayed until painting) that seems hard. | 412 // (decoding delayed until painting) that seems hard. |
413 notifyObservers(); | 413 notifyObservers(); |
414 } | 414 } |
415 | 415 |
416 void ImageResource::updateImageAndClearBuffer() | 416 void ImageResource::updateImageAndClearBuffer() |
417 { | 417 { |
418 clearImage(); | 418 clearImage(); |
419 updateImage(true); | 419 updateImage(true); |
420 m_data.clear(); | 420 clearData(); |
421 } | 421 } |
422 | 422 |
423 void ImageResource::finish(double loadFinishTime) | 423 void ImageResource::finish(double loadFinishTime) |
424 { | 424 { |
425 if (m_multipartParser) { | 425 if (m_multipartParser) { |
426 m_multipartParser->finish(); | 426 m_multipartParser->finish(); |
427 if (m_data) | 427 if (data()) |
428 updateImageAndClearBuffer(); | 428 updateImageAndClearBuffer(); |
429 } else { | 429 } else { |
430 updateImage(true); | 430 updateImage(true); |
431 // As encoded image data can be created from m_image (see | 431 // As encoded image data can be created from m_image (see |
432 // ImageResource::resourceBuffer(), we don't have to keep m_data. Let's | 432 // ImageResource::resourceBuffer(), we don't have to keep m_data. Let's |
433 // clear this. As for the lifetimes of m_image and m_data, see this | 433 // clear this. As for the lifetimes of m_image and m_data, see this |
434 // document: | 434 // document: |
435 // https://docs.google.com/document/d/1v0yTAZ6wkqX2U_M6BNIGUJpM1s0TIw1Vs
qpxoL7aciY/edit?usp=sharing | 435 // https://docs.google.com/document/d/1v0yTAZ6wkqX2U_M6BNIGUJpM1s0TIw1Vs
qpxoL7aciY/edit?usp=sharing |
436 m_data.clear(); | 436 clearData(); |
437 } | 437 } |
438 Resource::finish(loadFinishTime); | 438 Resource::finish(loadFinishTime); |
439 } | 439 } |
440 | 440 |
441 void ImageResource::error(const ResourceError& error) | 441 void ImageResource::error(const ResourceError& error) |
442 { | 442 { |
443 if (m_multipartParser) | 443 if (m_multipartParser) |
444 m_multipartParser->cancel(); | 444 m_multipartParser->cancel(); |
445 clear(); | 445 clear(); |
446 Resource::error(error); | 446 Resource::error(error); |
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
594 if (response().wasFetchedViaServiceWorker()) | 594 if (response().wasFetchedViaServiceWorker()) |
595 return response().serviceWorkerResponseType() != WebServiceWorkerRespons
eTypeOpaque; | 595 return response().serviceWorkerResponseType() != WebServiceWorkerRespons
eTypeOpaque; |
596 if (!getImage()->currentFrameHasSingleSecurityOrigin()) | 596 if (!getImage()->currentFrameHasSingleSecurityOrigin()) |
597 return false; | 597 return false; |
598 if (passesAccessControlCheck(securityOrigin)) | 598 if (passesAccessControlCheck(securityOrigin)) |
599 return true; | 599 return true; |
600 return !securityOrigin->taintsCanvas(response().url()); | 600 return !securityOrigin->taintsCanvas(response().url()); |
601 } | 601 } |
602 | 602 |
603 } // namespace blink | 603 } // namespace blink |
OLD | NEW |