1 /* 2 * Copyright (C) 2013 Google Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions are 6 * met: 7 * 8 * * Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * * Redistributions in binary form must reproduce the above 11 * copyright notice, this list of conditions and the following disclaimer 12 * in the documentation and/or other materials provided with the 13 * distribution. 14 * * Neither the name of Google Inc. nor the names of its 15 * contributors may be used to endorse or promote products derived from 16 * this software without specific prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 */ 30 31 #include "config.h" 32 #include "core/fetch/ResourceLoadPriorityOptimizer.h" 33 #include "core/rendering/RenderObject.h" 34 #include "platform/TraceEvent.h" 35 36 #include "wtf/Vector.h" 37 38 namespace blink { 39 40 ResourceLoadPriorityOptimizer* ResourceLoadPriorityOptimizer::resourceLoadPriorityOptimizer() 41 { 42 DEFINE_STATIC_LOCAL(ResourceLoadPriorityOptimizer, s_renderLoadOptimizer, ()); 43 return &s_renderLoadOptimizer; 44 } 45 46 ResourceLoadPriorityOptimizer::ResourceAndVisibility::ResourceAndVisibility(ImageResource* image, VisibilityStatus visibilityStatus, uint32_t screenArea) 47 : imageResource(image) 48 , status(visibilityStatus) 49 , screenArea(screenArea) 50 { 51 } 52 53 ResourceLoadPriorityOptimizer::ResourceAndVisibility::~ResourceAndVisibility() 54 { 55 } 56 57 ResourceLoadPriorityOptimizer::ResourceLoadPriorityOptimizer() 58 { 59 } 60 61 ResourceLoadPriorityOptimizer::~ResourceLoadPriorityOptimizer() 62 { 63 } 64 65 void ResourceLoadPriorityOptimizer::addRenderObject(RenderObject* renderer) 66 { 67 m_objects.add(renderer); 68 renderer->setHasPendingResourceUpdate(true); 69 } 70 71 void ResourceLoadPriorityOptimizer::removeRenderObject(RenderObject* renderer) 72 { 73 if (!renderer->hasPendingResourceUpdate()) 74 return; 75 m_objects.remove(renderer); 76 renderer->setHasPendingResourceUpdate(false); 77 } 78 79 void ResourceLoadPriorityOptimizer::updateAllImageResourcePriorities() 80 { 81 TRACE_EVENT0("blink", "ResourceLoadPriorityOptimizer::updateAllImageResourcePriorities"); 82 83 m_imageResources.clear(); 84 85 Vector<RenderObject*> objectsToRemove; 86 for (RenderObjectSet::iterator it = m_objects.begin(); it != m_objects.end(); ++it) { 87 RenderObject* obj = *it; 88 if (!obj->updateImageLoadingPriorities()) { 89 objectsToRemove.append(obj); 90 } 91 } 92 m_objects.removeAll(objectsToRemove); 93 94 updateImageResourcesWithLoadPriority(); 95 } 96 97 void ResourceLoadPriorityOptimizer::updateImageResourcesWithLoadPriority() 98 { 99 for (ImageResourceMap::iterator it = m_imageResources.begin(); it != m_imageResources.end(); ++it) { 100 ResourceLoadPriority priority = it->value->status == Visible ? 101 ResourceLoadPriorityLow : ResourceLoadPriorityVeryLow; 102 103 if (priority != it->value->imageResource->resourceRequest().priority()) { 104 it->value->imageResource->mutableResourceRequest().setPriority(priority, it->value->screenArea); 105 it->value->imageResource->didChangePriority(priority, it->value->screenArea); 106 } 107 } 108 m_imageResources.clear(); 109 } 110 111 void ResourceLoadPriorityOptimizer::notifyImageResourceVisibility(ImageResource* img, VisibilityStatus status, const LayoutRect& screenRect) 112 { 113 if (!img || img->isLoaded()) 114 return; 115 116 int screenArea = 0; 117 if (!screenRect.isEmpty() && status == Visible) 118 screenArea += static_cast<uint32_t>(screenRect.width() * screenRect.height()); 119 120 ImageResourceMap::AddResult result = m_imageResources.add(img->identifier(), adoptPtr(new ResourceAndVisibility(img, status, screenArea))); 121 if (!result.isNewEntry && status == Visible) { 122 result.storedValue->value->status = status; 123 result.storedValue->value->screenArea = status; 124 } 125 } 126 127 } 128