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 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
94 } | 94 } |
95 | 95 |
96 DEFINE_TRACE(ImageResource) | 96 DEFINE_TRACE(ImageResource) |
97 { | 97 { |
98 visitor->trace(m_multipartParser); | 98 visitor->trace(m_multipartParser); |
99 Resource::trace(visitor); | 99 Resource::trace(visitor); |
100 ImageObserver::trace(visitor); | 100 ImageObserver::trace(visitor); |
101 MultipartImageResourceParser::Client::trace(visitor); | 101 MultipartImageResourceParser::Client::trace(visitor); |
102 } | 102 } |
103 | 103 |
| 104 void ImageResource::notifyObserver(ImageResourceObserver* observer, bool isNotif
yingFinish, const IntRect* changeRect) |
| 105 { |
| 106 if (isNotifyingFinish) { |
| 107 observer->imageNotifyFinished(this); |
| 108 if (m_observers.contains(observer)) { |
| 109 m_finishedObservers.add(observer); |
| 110 m_observers.remove(observer); |
| 111 } |
| 112 } |
| 113 |
| 114 observer->imageChanged(this, changeRect); |
| 115 } |
| 116 |
104 void ImageResource::addObserver(ImageResourceObserver* observer) | 117 void ImageResource::addObserver(ImageResourceObserver* observer) |
105 { | 118 { |
106 willAddClientOrObserver(); | 119 willAddClientOrObserver(); |
107 | 120 |
108 m_observers.add(observer); | 121 m_observers.add(observer); |
109 | 122 |
110 if (!m_revalidatingRequest.isNull()) | 123 if (!m_revalidatingRequest.isNull()) |
111 return; | 124 return; |
112 | 125 |
113 if (m_data && !m_image && !errorOccurred()) { | 126 if (m_data && !m_image && !errorOccurred()) { |
114 createImage(); | 127 createImage(); |
115 m_image->setData(m_data, true); | 128 m_image->setData(m_data, true); |
116 } | 129 } |
117 | 130 |
118 if (m_image && !m_image->isNull()) | 131 if (m_image && !m_image->isNull()) { |
119 observer->imageChanged(this); | 132 bool isNotifyingFinish = !isLoading() && !stillNeedsLoad(); |
| 133 notifyObserver(observer, isNotifyingFinish); |
| 134 } |
120 } | 135 } |
121 | 136 |
122 void ImageResource::removeObserver(ImageResourceObserver* observer) | 137 void ImageResource::removeObserver(ImageResourceObserver* observer) |
123 { | 138 { |
124 ASSERT(observer); | 139 ASSERT(observer); |
125 ASSERT(m_observers.contains(observer)); | 140 |
126 m_observers.remove(observer); | 141 if (m_observers.contains(observer)) |
| 142 m_observers.remove(observer); |
| 143 else if (m_finishedObservers.contains(observer)) |
| 144 m_finishedObservers.remove(observer); |
| 145 else |
| 146 ASSERT_NOT_REACHED(); |
| 147 |
127 didRemoveClientOrObserver(); | 148 didRemoveClientOrObserver(); |
128 } | 149 } |
129 | 150 |
| 151 static void priorityFromObserver(const ImageResourceObserver* observer, Resource
Priority& priority) |
| 152 { |
| 153 ResourcePriority nextPriority = observer->computeResourcePriority(); |
| 154 if (nextPriority.visibility == ResourcePriority::NotVisible) |
| 155 return; |
| 156 priority.visibility = ResourcePriority::Visible; |
| 157 priority.intraPriorityValue += nextPriority.intraPriorityValue; |
| 158 } |
| 159 |
130 ResourcePriority ImageResource::priorityFromObservers() | 160 ResourcePriority ImageResource::priorityFromObservers() |
131 { | 161 { |
132 ResourcePriority priority; | 162 ResourcePriority priority; |
133 ImageResourceObserverWalker w(m_observers); | 163 |
134 while (const auto* observer = w.next()) { | 164 ImageResourceObserverWalker finishedWalker(m_finishedObservers); |
135 ResourcePriority nextPriority = observer->computeResourcePriority(); | 165 while (const auto* observer = finishedWalker.next()) { |
136 if (nextPriority.visibility == ResourcePriority::NotVisible) | 166 priorityFromObserver(observer, priority); |
137 continue; | |
138 priority.visibility = ResourcePriority::Visible; | |
139 priority.intraPriorityValue += nextPriority.intraPriorityValue; | |
140 } | 167 } |
| 168 |
| 169 ImageResourceObserverWalker walker(m_observers); |
| 170 while (const auto* observer = walker.next()) { |
| 171 priorityFromObserver(observer, priority); |
| 172 } |
| 173 |
141 return priority; | 174 return priority; |
142 } | 175 } |
143 | 176 |
144 bool ImageResource::isSafeToUnlock() const | 177 bool ImageResource::isSafeToUnlock() const |
145 { | 178 { |
146 // Note that |m_image| holds a reference to |m_data| in addition to the one
held by the Resource parent class. | 179 // Note that |m_image| holds a reference to |m_data| in addition to the one
held by the Resource parent class. |
147 return !m_image || (m_image->hasOneRef() && m_data->refCount() == 2); | 180 return !m_image || (m_image->hasOneRef() && m_data->refCount() == 2); |
148 } | 181 } |
149 | 182 |
150 void ImageResource::destroyDecodedDataForFailedRevalidation() | 183 void ImageResource::destroyDecodedDataForFailedRevalidation() |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
252 return size; | 285 return size; |
253 | 286 |
254 // Don't let images that have a width/height >= 1 shrink below 1 when zoomed
. | 287 // Don't let images that have a width/height >= 1 shrink below 1 when zoomed
. |
255 LayoutSize minimumSize(size.width() > LayoutUnit() ? LayoutUnit(1) : LayoutU
nit(), | 288 LayoutSize minimumSize(size.width() > LayoutUnit() ? LayoutUnit(1) : LayoutU
nit(), |
256 LayoutUnit(size.height() > LayoutUnit() ? LayoutUnit(1) : LayoutUnit()))
; | 289 LayoutUnit(size.height() > LayoutUnit() ? LayoutUnit(1) : LayoutUnit()))
; |
257 size.scale(multiplier); | 290 size.scale(multiplier); |
258 size.clampToMinimumSize(minimumSize); | 291 size.clampToMinimumSize(minimumSize); |
259 return size; | 292 return size; |
260 } | 293 } |
261 | 294 |
262 void ImageResource::notifyObservers(const IntRect* changeRect) | 295 void ImageResource::notifyObservers(bool isNotifyingFinish, const IntRect* chang
eRect) |
263 { | 296 { |
264 ImageResourceObserverWalker w(m_observers); | 297 ImageResourceObserverWalker finishedWalker(m_finishedObservers); |
265 while (auto* observer = w.next()) { | 298 while (auto* observer = finishedWalker.next()) { |
266 observer->imageChanged(this, changeRect); | 299 notifyObserver(observer, false, changeRect); |
| 300 } |
| 301 |
| 302 ImageResourceObserverWalker walker(m_observers); |
| 303 while (auto* observer = walker.next()) { |
| 304 notifyObserver(observer, isNotifyingFinish, changeRect); |
267 } | 305 } |
268 } | 306 } |
269 | 307 |
270 void ImageResource::clear() | 308 void ImageResource::clear() |
271 { | 309 { |
272 prune(); | 310 prune(); |
273 clearImage(); | 311 clearImage(); |
274 setEncodedSize(0); | 312 setEncodedSize(0); |
275 } | 313 } |
276 | 314 |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
326 if (sizeAvailable || allDataReceived) { | 364 if (sizeAvailable || allDataReceived) { |
327 if (!m_image || m_image->isNull()) { | 365 if (!m_image || m_image->isNull()) { |
328 error(errorOccurred() ? getStatus() : DecodeError); | 366 error(errorOccurred() ? getStatus() : DecodeError); |
329 if (memoryCache()->contains(this)) | 367 if (memoryCache()->contains(this)) |
330 memoryCache()->remove(this); | 368 memoryCache()->remove(this); |
331 return; | 369 return; |
332 } | 370 } |
333 | 371 |
334 // It would be nice to only redraw the decoded band of the image, but wi
th the current design | 372 // It would be nice to only redraw the decoded band of the image, but wi
th the current design |
335 // (decoding delayed until painting) that seems hard. | 373 // (decoding delayed until painting) that seems hard. |
336 notifyObservers(); | 374 notifyObservers(allDataReceived); |
337 } | 375 } |
338 } | 376 } |
339 | 377 |
340 void ImageResource::finish() | 378 void ImageResource::finish() |
341 { | 379 { |
342 if (m_multipartParser) { | 380 if (m_multipartParser) { |
343 m_multipartParser->finish(); | 381 m_multipartParser->finish(); |
344 if (m_data) { | 382 if (m_data) { |
345 clearImage(); | 383 clearImage(); |
346 updateImage(true); | 384 updateImage(true); |
347 m_data.clear(); | 385 m_data.clear(); |
348 } | 386 } |
349 } else { | 387 } else { |
350 updateImage(true); | 388 updateImage(true); |
351 } | 389 } |
352 Resource::finish(); | 390 Resource::finish(); |
353 } | 391 } |
354 | 392 |
355 void ImageResource::error(Resource::Status status) | 393 void ImageResource::error(Resource::Status status) |
356 { | 394 { |
357 if (m_multipartParser) | 395 if (m_multipartParser) |
358 m_multipartParser->cancel(); | 396 m_multipartParser->cancel(); |
359 clear(); | 397 clear(); |
360 Resource::error(status); | 398 Resource::error(status); |
361 notifyObservers(); | 399 notifyObservers(true); |
362 } | 400 } |
363 | 401 |
364 void ImageResource::responseReceived(const ResourceResponse& response, PassOwnPt
r<WebDataConsumerHandle> handle) | 402 void ImageResource::responseReceived(const ResourceResponse& response, PassOwnPt
r<WebDataConsumerHandle> handle) |
365 { | 403 { |
366 ASSERT(!handle); | 404 ASSERT(!handle); |
367 ASSERT(!m_multipartParser); | 405 ASSERT(!m_multipartParser); |
368 // If there's no boundary, just handle the request normally. | 406 // If there's no boundary, just handle the request normally. |
369 if (response.isMultipart() && !response.multipartBoundary().isEmpty()) | 407 if (response.isMultipart() && !response.multipartBoundary().isEmpty()) |
370 m_multipartParser = new MultipartImageResourceParser(response, response.
multipartBoundary(), this); | 408 m_multipartParser = new MultipartImageResourceParser(response, response.
multipartBoundary(), this); |
371 Resource::responseReceived(response, handle); | 409 Resource::responseReceived(response, handle); |
(...skipping 26 matching lines...) Expand all Loading... |
398 // to update MemoryCache. | 436 // to update MemoryCache. |
399 if (decodedSize() != 0) | 437 if (decodedSize() != 0) |
400 Resource::didAccessDecodedData(); | 438 Resource::didAccessDecodedData(); |
401 } | 439 } |
402 | 440 |
403 bool ImageResource::shouldPauseAnimation(const blink::Image* image) | 441 bool ImageResource::shouldPauseAnimation(const blink::Image* image) |
404 { | 442 { |
405 if (!image || image != m_image) | 443 if (!image || image != m_image) |
406 return false; | 444 return false; |
407 | 445 |
408 ImageResourceObserverWalker w(m_observers); | 446 ImageResourceObserverWalker finishedWalker(m_finishedObservers); |
409 while (auto* observer = w.next()) { | 447 while (auto* observer = finishedWalker.next()) { |
410 if (observer->willRenderImage()) | 448 if (observer->willRenderImage()) |
411 return false; | 449 return false; |
412 } | 450 } |
| 451 |
| 452 ImageResourceObserverWalker walker(m_observers); |
| 453 while (auto* observer = walker.next()) { |
| 454 if (observer->willRenderImage()) |
| 455 return false; |
| 456 } |
| 457 |
413 return true; | 458 return true; |
414 } | 459 } |
415 | 460 |
416 void ImageResource::animationAdvanced(const blink::Image* image) | 461 void ImageResource::animationAdvanced(const blink::Image* image) |
417 { | 462 { |
418 if (!image || image != m_image) | 463 if (!image || image != m_image) |
419 return; | 464 return; |
420 notifyObservers(); | 465 notifyObservers(false); |
421 } | 466 } |
422 | 467 |
423 void ImageResource::updateImageAnimationPolicy() | 468 void ImageResource::updateImageAnimationPolicy() |
424 { | 469 { |
425 if (!m_image) | 470 if (!m_image) |
426 return; | 471 return; |
427 | 472 |
428 ImageAnimationPolicy newPolicy = ImageAnimationPolicyAllowed; | 473 ImageAnimationPolicy newPolicy = ImageAnimationPolicyAllowed; |
429 ImageResourceObserverWalker w(m_observers); | 474 |
430 while (auto* observer = w.next()) { | 475 ImageResourceObserverWalker finishedWalker(m_finishedObservers); |
| 476 while (auto* observer = finishedWalker.next()) { |
431 if (observer->getImageAnimationPolicy(newPolicy)) | 477 if (observer->getImageAnimationPolicy(newPolicy)) |
432 break; | 478 break; |
433 } | 479 } |
| 480 |
| 481 ImageResourceObserverWalker walker(m_observers); |
| 482 while (auto* observer = walker.next()) { |
| 483 if (observer->getImageAnimationPolicy(newPolicy)) |
| 484 break; |
| 485 } |
434 | 486 |
435 if (m_image->animationPolicy() != newPolicy) { | 487 if (m_image->animationPolicy() != newPolicy) { |
436 m_image->resetAnimation(); | 488 m_image->resetAnimation(); |
437 m_image->setAnimationPolicy(newPolicy); | 489 m_image->setAnimationPolicy(newPolicy); |
438 } | 490 } |
439 } | 491 } |
440 | 492 |
441 void ImageResource::reloadIfLoFi(ResourceFetcher* fetcher) | 493 void ImageResource::reloadIfLoFi(ResourceFetcher* fetcher) |
442 { | 494 { |
443 if (!m_response.httpHeaderField("chrome-proxy").contains("q=low")) | 495 if (!m_response.httpHeaderField("chrome-proxy").contains("q=low")) |
444 return; | 496 return; |
445 m_resourceRequest.setCachePolicy(ResourceRequestCachePolicy::ReloadBypassing
Cache); | 497 m_resourceRequest.setCachePolicy(ResourceRequestCachePolicy::ReloadBypassing
Cache); |
446 m_resourceRequest.setLoFiState(WebURLRequest::LoFiOff); | 498 m_resourceRequest.setLoFiState(WebURLRequest::LoFiOff); |
447 error(Resource::LoadError); | 499 error(Resource::LoadError); |
448 load(fetcher); | 500 load(fetcher); |
449 } | 501 } |
450 | 502 |
451 void ImageResource::changedInRect(const blink::Image* image, const IntRect& rect
) | 503 void ImageResource::changedInRect(const blink::Image* image, const IntRect& rect
) |
452 { | 504 { |
453 if (!image || image != m_image) | 505 if (!image || image != m_image) |
454 return; | 506 return; |
455 notifyObservers(&rect); | 507 notifyObservers(false, &rect); |
456 } | 508 } |
457 | 509 |
458 void ImageResource::onePartInMultipartReceived(const ResourceResponse& response) | 510 void ImageResource::onePartInMultipartReceived(const ResourceResponse& response) |
459 { | 511 { |
460 ASSERT(m_multipartParser); | 512 ASSERT(m_multipartParser); |
461 | 513 |
462 m_response = response; | 514 m_response = response; |
463 if (m_multipartParsingState == MultipartParsingState::WaitingForFirstPart) { | 515 if (m_multipartParsingState == MultipartParsingState::WaitingForFirstPart) { |
464 // We have nothing to do because we don't have any data. | 516 // We have nothing to do because we don't have any data. |
465 m_multipartParsingState = MultipartParsingState::ParsingFirstPart; | 517 m_multipartParsingState = MultipartParsingState::ParsingFirstPart; |
(...skipping 25 matching lines...) Expand all Loading... |
491 if (response().wasFetchedViaServiceWorker()) | 543 if (response().wasFetchedViaServiceWorker()) |
492 return response().serviceWorkerResponseType() != WebServiceWorkerRespons
eTypeOpaque; | 544 return response().serviceWorkerResponseType() != WebServiceWorkerRespons
eTypeOpaque; |
493 if (!getImage()->currentFrameHasSingleSecurityOrigin()) | 545 if (!getImage()->currentFrameHasSingleSecurityOrigin()) |
494 return false; | 546 return false; |
495 if (passesAccessControlCheck(securityOrigin)) | 547 if (passesAccessControlCheck(securityOrigin)) |
496 return true; | 548 return true; |
497 return !securityOrigin->taintsCanvas(response().url()); | 549 return !securityOrigin->taintsCanvas(response().url()); |
498 } | 550 } |
499 | 551 |
500 } // namespace blink | 552 } // namespace blink |
OLD | NEW |