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 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
112 } | 112 } |
113 | 113 |
114 void ImageResource::load(ResourceFetcher* fetcher, const ResourceLoaderOptions&
options) | 114 void ImageResource::load(ResourceFetcher* fetcher, const ResourceLoaderOptions&
options) |
115 { | 115 { |
116 if (!fetcher || fetcher->autoLoadImages()) | 116 if (!fetcher || fetcher->autoLoadImages()) |
117 Resource::load(fetcher, options); | 117 Resource::load(fetcher, options); |
118 else | 118 else |
119 setLoading(false); | 119 setLoading(false); |
120 } | 120 } |
121 | 121 |
| 122 void ImageResource::notifyObserver(ImageResourceObserver* observer, bool isNotif
yingFinish, const IntRect* changeRect) |
| 123 { |
| 124 observer->imageChanged(isNotifyingFinish, this, changeRect); |
| 125 if (isNotifyingFinish && m_observers.contains(observer)) { |
| 126 m_finishedObservers.add(observer); |
| 127 m_observers.remove(observer); |
| 128 } |
| 129 } |
| 130 |
122 void ImageResource::addObserver(ImageResourceObserver* observer) | 131 void ImageResource::addObserver(ImageResourceObserver* observer) |
123 { | 132 { |
124 willAddClientOrObserver(); | 133 willAddClientOrObserver(); |
125 | 134 |
126 m_observers.add(observer); | 135 m_observers.add(observer); |
127 | 136 |
128 if (!m_revalidatingRequest.isNull()) | 137 if (!m_revalidatingRequest.isNull()) |
129 return; | 138 return; |
130 | 139 |
131 if (m_data && !m_image && !errorOccurred()) { | 140 if (m_data && !m_image && !errorOccurred()) { |
132 createImage(); | 141 createImage(); |
133 m_image->setData(m_data, true); | 142 m_image->setData(m_data, true); |
134 } | 143 } |
135 | 144 |
136 if (m_image && !m_image->isNull()) | 145 if (m_image && !m_image->isNull()) { |
137 observer->imageChanged(this); | 146 bool isNotifyingFinish = !isLoading() && !stillNeedsLoad(); |
| 147 notifyObserver(observer, isNotifyingFinish); |
| 148 } |
138 } | 149 } |
139 | 150 |
140 void ImageResource::removeObserver(ImageResourceObserver* observer) | 151 void ImageResource::removeObserver(ImageResourceObserver* observer) |
141 { | 152 { |
142 ASSERT(observer); | 153 ASSERT(observer); |
143 ASSERT(m_observers.contains(observer)); | 154 |
144 m_observers.remove(observer); | 155 if (m_observers.contains(observer)) |
| 156 m_observers.remove(observer); |
| 157 else if (m_finishedObservers.contains(observer)) |
| 158 m_finishedObservers.remove(observer); |
| 159 else |
| 160 ASSERT_NOT_REACHED(); |
| 161 |
145 didRemoveClientOrObserver(); | 162 didRemoveClientOrObserver(); |
146 } | 163 } |
147 | 164 |
| 165 static void priorityFromObserver(const ImageResourceObserver* observer, Resource
Priority& priority) |
| 166 { |
| 167 ResourcePriority nextPriority = observer->computeResourcePriority(); |
| 168 if (nextPriority.visibility == ResourcePriority::NotVisible) |
| 169 return; |
| 170 priority.visibility = ResourcePriority::Visible; |
| 171 priority.intraPriorityValue += nextPriority.intraPriorityValue; |
| 172 } |
| 173 |
148 ResourcePriority ImageResource::priorityFromObservers() | 174 ResourcePriority ImageResource::priorityFromObservers() |
149 { | 175 { |
150 ResourcePriority priority; | 176 ResourcePriority priority; |
151 ImageResourceObserverWalker w(m_observers); | 177 |
| 178 ImageResourceObserverWalker w(m_finishedObservers); |
152 while (const auto* observer = w.next()) { | 179 while (const auto* observer = w.next()) { |
153 ResourcePriority nextPriority = observer->computeResourcePriority(); | 180 priorityFromObserver(observer, priority); |
154 if (nextPriority.visibility == ResourcePriority::NotVisible) | |
155 continue; | |
156 priority.visibility = ResourcePriority::Visible; | |
157 priority.intraPriorityValue += nextPriority.intraPriorityValue; | |
158 } | 181 } |
| 182 |
| 183 ImageResourceObserverWalker w2(m_observers); |
| 184 while (const auto* observer = w2.next()) { |
| 185 priorityFromObserver(observer, priority); |
| 186 } |
| 187 |
159 return priority; | 188 return priority; |
160 } | 189 } |
161 | 190 |
162 bool ImageResource::isSafeToUnlock() const | 191 bool ImageResource::isSafeToUnlock() const |
163 { | 192 { |
164 // Note that |m_image| holds a reference to |m_data| in addition to the one
held by the Resource parent class. | 193 // Note that |m_image| holds a reference to |m_data| in addition to the one
held by the Resource parent class. |
165 return !m_image || (m_image->hasOneRef() && m_data->refCount() == 2); | 194 return !m_image || (m_image->hasOneRef() && m_data->refCount() == 2); |
166 } | 195 } |
167 | 196 |
168 void ImageResource::destroyDecodedDataForFailedRevalidation() | 197 void ImageResource::destroyDecodedDataForFailedRevalidation() |
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
276 size.clampToMinimumSize(minimumSize); | 305 size.clampToMinimumSize(minimumSize); |
277 return size; | 306 return size; |
278 } | 307 } |
279 | 308 |
280 void ImageResource::computeIntrinsicDimensions(FloatSize& intrinsicSize, FloatSi
ze& intrinsicRatio) | 309 void ImageResource::computeIntrinsicDimensions(FloatSize& intrinsicSize, FloatSi
ze& intrinsicRatio) |
281 { | 310 { |
282 if (m_image) | 311 if (m_image) |
283 m_image->computeIntrinsicDimensions(intrinsicSize, intrinsicRatio); | 312 m_image->computeIntrinsicDimensions(intrinsicSize, intrinsicRatio); |
284 } | 313 } |
285 | 314 |
286 void ImageResource::notifyObservers(const IntRect* changeRect) | 315 void ImageResource::notifyObservers(bool isNotifyingFinish, const IntRect* chang
eRect) |
287 { | 316 { |
288 ImageResourceObserverWalker w(m_observers); | 317 ImageResourceObserverWalker w(m_finishedObservers); |
289 while (auto* observer = w.next()) { | 318 while (auto* observer = w.next()) { |
290 observer->imageChanged(this, changeRect); | 319 notifyObserver(observer, false, changeRect); |
| 320 } |
| 321 |
| 322 ImageResourceObserverWalker w2(m_observers); |
| 323 while (auto* observer = w2.next()) { |
| 324 notifyObserver(observer, isNotifyingFinish, changeRect); |
291 } | 325 } |
292 } | 326 } |
293 | 327 |
294 void ImageResource::clear() | 328 void ImageResource::clear() |
295 { | 329 { |
296 prune(); | 330 prune(); |
297 clearImage(); | 331 clearImage(); |
298 setEncodedSize(0); | 332 setEncodedSize(0); |
299 } | 333 } |
300 | 334 |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
350 if (sizeAvailable || allDataReceived) { | 384 if (sizeAvailable || allDataReceived) { |
351 if (!m_image || m_image->isNull()) { | 385 if (!m_image || m_image->isNull()) { |
352 error(errorOccurred() ? getStatus() : DecodeError); | 386 error(errorOccurred() ? getStatus() : DecodeError); |
353 if (memoryCache()->contains(this)) | 387 if (memoryCache()->contains(this)) |
354 memoryCache()->remove(this); | 388 memoryCache()->remove(this); |
355 return; | 389 return; |
356 } | 390 } |
357 | 391 |
358 // It would be nice to only redraw the decoded band of the image, but wi
th the current design | 392 // It would be nice to only redraw the decoded band of the image, but wi
th the current design |
359 // (decoding delayed until painting) that seems hard. | 393 // (decoding delayed until painting) that seems hard. |
360 notifyObservers(); | 394 notifyObservers(allDataReceived); |
361 } | 395 } |
362 } | 396 } |
363 | 397 |
364 void ImageResource::finish() | 398 void ImageResource::finish() |
365 { | 399 { |
366 if (m_multipartParser) { | 400 if (m_multipartParser) { |
367 m_multipartParser->finish(); | 401 m_multipartParser->finish(); |
368 if (m_data) { | 402 if (m_data) { |
369 clearImage(); | 403 clearImage(); |
370 updateImage(true); | 404 updateImage(true); |
371 m_data.clear(); | 405 m_data.clear(); |
372 } | 406 } |
373 } else { | 407 } else { |
374 updateImage(true); | 408 updateImage(true); |
375 } | 409 } |
376 Resource::finish(); | 410 Resource::finish(); |
377 } | 411 } |
378 | 412 |
379 void ImageResource::error(Resource::Status status) | 413 void ImageResource::error(Resource::Status status) |
380 { | 414 { |
381 if (m_multipartParser) | 415 if (m_multipartParser) |
382 m_multipartParser->cancel(); | 416 m_multipartParser->cancel(); |
383 clear(); | 417 clear(); |
384 Resource::error(status); | 418 Resource::error(status); |
385 notifyObservers(); | 419 notifyObservers(true); |
386 } | 420 } |
387 | 421 |
388 void ImageResource::responseReceived(const ResourceResponse& response, PassOwnPt
r<WebDataConsumerHandle> handle) | 422 void ImageResource::responseReceived(const ResourceResponse& response, PassOwnPt
r<WebDataConsumerHandle> handle) |
389 { | 423 { |
390 ASSERT(!handle); | 424 ASSERT(!handle); |
391 ASSERT(!m_multipartParser); | 425 ASSERT(!m_multipartParser); |
392 // If there's no boundary, just handle the request normally. | 426 // If there's no boundary, just handle the request normally. |
393 if (response.isMultipart() && !response.multipartBoundary().isEmpty()) | 427 if (response.isMultipart() && !response.multipartBoundary().isEmpty()) |
394 m_multipartParser = new MultipartImageResourceParser(response, response.
multipartBoundary(), this); | 428 m_multipartParser = new MultipartImageResourceParser(response, response.
multipartBoundary(), this); |
395 Resource::responseReceived(response, handle); | 429 Resource::responseReceived(response, handle); |
(...skipping 26 matching lines...) Expand all Loading... |
422 // to update MemoryCache. | 456 // to update MemoryCache. |
423 if (decodedSize() != 0) | 457 if (decodedSize() != 0) |
424 Resource::didAccessDecodedData(); | 458 Resource::didAccessDecodedData(); |
425 } | 459 } |
426 | 460 |
427 bool ImageResource::shouldPauseAnimation(const blink::Image* image) | 461 bool ImageResource::shouldPauseAnimation(const blink::Image* image) |
428 { | 462 { |
429 if (!image || image != m_image) | 463 if (!image || image != m_image) |
430 return false; | 464 return false; |
431 | 465 |
432 ImageResourceObserverWalker w(m_observers); | 466 ImageResourceObserverWalker w(m_finishedObservers); |
433 while (auto* observer = w.next()) { | 467 while (auto* observer = w.next()) { |
434 if (observer->willRenderImage()) | 468 if (observer->willRenderImage()) |
435 return false; | 469 return false; |
436 } | 470 } |
| 471 |
| 472 ImageResourceObserverWalker w2(m_observers); |
| 473 while (auto* observer = w2.next()) { |
| 474 if (observer->willRenderImage()) |
| 475 return false; |
| 476 } |
| 477 |
437 return true; | 478 return true; |
438 } | 479 } |
439 | 480 |
440 void ImageResource::animationAdvanced(const blink::Image* image) | 481 void ImageResource::animationAdvanced(const blink::Image* image) |
441 { | 482 { |
442 if (!image || image != m_image) | 483 if (!image || image != m_image) |
443 return; | 484 return; |
444 notifyObservers(); | 485 notifyObservers(false); |
445 } | 486 } |
446 | 487 |
447 void ImageResource::updateImageAnimationPolicy() | 488 void ImageResource::updateImageAnimationPolicy() |
448 { | 489 { |
449 if (!m_image) | 490 if (!m_image) |
450 return; | 491 return; |
451 | 492 |
452 ImageAnimationPolicy newPolicy = ImageAnimationPolicyAllowed; | 493 ImageAnimationPolicy newPolicy = ImageAnimationPolicyAllowed; |
453 ImageResourceObserverWalker w(m_observers); | 494 |
| 495 ImageResourceObserverWalker w(m_finishedObservers); |
454 while (auto* observer = w.next()) { | 496 while (auto* observer = w.next()) { |
455 if (observer->getImageAnimationPolicy(newPolicy)) | 497 if (observer->getImageAnimationPolicy(newPolicy)) |
456 break; | 498 break; |
457 } | 499 } |
458 | 500 |
| 501 ImageResourceObserverWalker w2(m_observers); |
| 502 while (auto* observer = w2.next()) { |
| 503 if (observer->getImageAnimationPolicy(newPolicy)) |
| 504 break; |
| 505 } |
| 506 |
459 if (m_image->animationPolicy() != newPolicy) { | 507 if (m_image->animationPolicy() != newPolicy) { |
460 m_image->resetAnimation(); | 508 m_image->resetAnimation(); |
461 m_image->setAnimationPolicy(newPolicy); | 509 m_image->setAnimationPolicy(newPolicy); |
462 } | 510 } |
463 } | 511 } |
464 | 512 |
465 void ImageResource::reloadIfLoFi(ResourceFetcher* fetcher) | 513 void ImageResource::reloadIfLoFi(ResourceFetcher* fetcher) |
466 { | 514 { |
467 if (!m_response.httpHeaderField("chrome-proxy").contains("q=low")) | 515 if (!m_response.httpHeaderField("chrome-proxy").contains("q=low")) |
468 return; | 516 return; |
469 m_resourceRequest.setCachePolicy(ResourceRequestCachePolicy::ReloadBypassing
Cache); | 517 m_resourceRequest.setCachePolicy(ResourceRequestCachePolicy::ReloadBypassing
Cache); |
470 m_resourceRequest.setLoFiState(WebURLRequest::LoFiOff); | 518 m_resourceRequest.setLoFiState(WebURLRequest::LoFiOff); |
471 error(Resource::LoadError); | 519 error(Resource::LoadError); |
472 load(fetcher, fetcher->defaultResourceOptions()); | 520 load(fetcher, fetcher->defaultResourceOptions()); |
473 } | 521 } |
474 | 522 |
475 void ImageResource::changedInRect(const blink::Image* image, const IntRect& rect
) | 523 void ImageResource::changedInRect(const blink::Image* image, const IntRect& rect
) |
476 { | 524 { |
477 if (!image || image != m_image) | 525 if (!image || image != m_image) |
478 return; | 526 return; |
479 notifyObservers(&rect); | 527 notifyObservers(false, &rect); |
480 } | 528 } |
481 | 529 |
482 void ImageResource::onePartInMultipartReceived(const ResourceResponse& response,
bool isFirstPart) | 530 void ImageResource::onePartInMultipartReceived(const ResourceResponse& response,
bool isFirstPart) |
483 { | 531 { |
484 ASSERT(isMultipartImage()); | 532 ASSERT(isMultipartImage()); |
485 m_response = response; | 533 m_response = response; |
486 if (m_data) { | 534 if (m_data) { |
487 clear(); | 535 clear(); |
488 updateImage(true); | 536 updateImage(true); |
489 m_data.clear(); | 537 m_data.clear(); |
(...skipping 15 matching lines...) Expand all Loading... |
505 if (response().wasFetchedViaServiceWorker()) | 553 if (response().wasFetchedViaServiceWorker()) |
506 return response().serviceWorkerResponseType() != WebServiceWorkerRespons
eTypeOpaque; | 554 return response().serviceWorkerResponseType() != WebServiceWorkerRespons
eTypeOpaque; |
507 if (!image()->currentFrameHasSingleSecurityOrigin()) | 555 if (!image()->currentFrameHasSingleSecurityOrigin()) |
508 return false; | 556 return false; |
509 if (passesAccessControlCheck(securityOrigin)) | 557 if (passesAccessControlCheck(securityOrigin)) |
510 return true; | 558 return true; |
511 return !securityOrigin->taintsCanvas(response().url()); | 559 return !securityOrigin->taintsCanvas(response().url()); |
512 } | 560 } |
513 | 561 |
514 } // namespace blink | 562 } // namespace blink |
OLD | NEW |