1b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam/* 2b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * Copyright (C) Research In Motion Limited 2010. All rights reserved. 36e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom * 46e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom * This library is free software; you can redistribute it and/or 5b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * modify it under the terms of the GNU Library General Public 6b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * License as published by the Free Software Foundation; either 7b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * version 2 of the License, or (at your option) any later version. 8b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * 9b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * This library is distributed in the hope that it will be useful, 10b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * but WITHOUT ANY WARRANTY; without even the implied warranty of 11b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * Library General Public License for more details. 13b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * 14b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * You should have received a copy of the GNU Library General Public License 15b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * along with this library; see the file COPYING.LIB. If not, write to 16b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 17b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * Boston, MA 02110-1301, USA. 18b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam */ 19b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 20b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam#include "config.h" 21b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam#include "SVGResourcesCache.h" 22b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 23b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam#if ENABLE(SVG) 24b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam#include "RenderSVGResourceContainer.h" 25b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam#include "SVGDocumentExtensions.h" 26b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam#include "SVGResources.h" 27b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam#include "SVGResourcesCycleSolver.h" 28b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 29b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamnamespace WebCore { 30b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 31b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter HallamSVGResourcesCache::SVGResourcesCache() 32b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam{ 33b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam} 34b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 35b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter HallamSVGResourcesCache::~SVGResourcesCache() 36b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam{ 37b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam deleteAllValues(m_cache); 38b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam} 39b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 40b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamvoid SVGResourcesCache::addResourcesFromRenderObject(RenderObject* object, const RenderStyle* style) 41b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam{ 42b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam ASSERT(object); 43b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam ASSERT(style); 44b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam ASSERT(!m_cache.contains(object)); 45b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 46b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam const SVGRenderStyle* svgStyle = style->svgStyle(); 47b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam ASSERT(svgStyle); 48b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 49b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // Build a list of all resources associated with the passed RenderObject 50b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam SVGResources* resources = new SVGResources; 51b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam if (!resources->buildCachedResources(object, svgStyle)) { 52b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam delete resources; 53b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam return; 54b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 55b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 56b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // Put object in cache. 57b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam m_cache.set(object, resources); 58b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 59b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // Run cycle-detection _afterwards_, so self-references can be caught as well. 60b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam SVGResourcesCycleSolver solver(object, resources); 61b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam solver.resolveCycles(); 62b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 63b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // Walk resources and register the render object at each resources. 64b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam HashSet<RenderSVGResourceContainer*> resourceSet; 65b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam resources->buildSetOfResources(resourceSet); 66b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 676e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom HashSet<RenderSVGResourceContainer*>::iterator end = resourceSet.end(); 686e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom for (HashSet<RenderSVGResourceContainer*>::iterator it = resourceSet.begin(); it != end; ++it) 696e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom (*it)->addClient(object); 706e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom} 716e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom 726e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstromvoid SVGResourcesCache::removeResourcesFromRenderObject(RenderObject* object) 736e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom{ 746e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom if (!m_cache.contains(object)) 756e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom return; 766e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom 776e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom SVGResources* resources = m_cache.get(object); 786e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom 796e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom // Walk resources and register the render object at each resources. 806e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom HashSet<RenderSVGResourceContainer*> resourceSet; 816e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom resources->buildSetOfResources(resourceSet); 826e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom 836e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom HashSet<RenderSVGResourceContainer*>::iterator end = resourceSet.end(); 846e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom for (HashSet<RenderSVGResourceContainer*>::iterator it = resourceSet.begin(); it != end; ++it) 856e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom (*it)->removeClient(object); 86b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 876e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom delete m_cache.take(object); 88b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam} 89b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 90b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamstatic inline SVGResourcesCache* resourcesCacheFromRenderObject(RenderObject* renderer) 91b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam{ 92b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam Document* document = renderer->document(); 93b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam ASSERT(document); 94b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 95b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam SVGDocumentExtensions* extensions = document->accessSVGExtensions(); 96b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam ASSERT(extensions); 97b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 98b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam SVGResourcesCache* cache = extensions->resourcesCache(); 99b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam ASSERT(cache); 100b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 101b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam return cache; 102b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam} 103b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 104b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter HallamSVGResources* SVGResourcesCache::cachedResourcesForRenderObject(RenderObject* renderer) 105b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam{ 106b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam ASSERT(renderer); 107b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam SVGResourcesCache* cache = resourcesCacheFromRenderObject(renderer); 108b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam if (!cache->m_cache.contains(renderer)) 109b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam return 0; 110b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 111b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam return cache->m_cache.get(renderer); 112b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam} 113b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 114b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamvoid SVGResourcesCache::clientLayoutChanged(RenderObject* object) 115b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam{ 116b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam SVGResources* resources = SVGResourcesCache::cachedResourcesForRenderObject(object); 117b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam if (!resources) 118b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam return; 119b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 120b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam resources->removeClientFromCache(object); 121b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam} 122b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 123b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamvoid SVGResourcesCache::clientStyleChanged(RenderObject* renderer, StyleDifference diff, const RenderStyle* newStyle) 124b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam{ 125b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam ASSERT(renderer); 126b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam if (diff == StyleDifferenceEqual) 127b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam return; 128b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 129b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // In this case the proper SVGFE*Element will imply whether the modifided CSS properties implies a relayout or repaint. 130b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam if (renderer->isSVGResourceFilterPrimitive() && diff == StyleDifferenceRepaint) 131c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom return; 132c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom 133c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom clientUpdatedFromElement(renderer, newStyle); 134c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer, false); 135c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom} 136b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 137b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamvoid SVGResourcesCache::clientUpdatedFromElement(RenderObject* renderer, const RenderStyle* newStyle) 138b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam{ 139b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam ASSERT(renderer); 140b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam ASSERT(renderer->parent()); 141b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 142b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam SVGResourcesCache* cache = resourcesCacheFromRenderObject(renderer); 143b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam cache->removeResourcesFromRenderObject(renderer); 144b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam cache->addResourcesFromRenderObject(renderer, newStyle); 145b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam} 146b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 147b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamvoid SVGResourcesCache::clientDestroyed(RenderObject* renderer) 148b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam{ 149b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam ASSERT(renderer); 150b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam SVGResourcesCache* cache = resourcesCacheFromRenderObject(renderer); 151b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam cache->removeResourcesFromRenderObject(renderer); 152b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam} 153b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 154b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamvoid SVGResourcesCache::resourceDestroyed(RenderSVGResourceContainer* resource) 155b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam{ 156b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam ASSERT(resource); 157b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam SVGResourcesCache* cache = resourcesCacheFromRenderObject(resource); 158b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 159b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // The resource itself may have clients, that need to be notified. 160b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam cache->removeResourcesFromRenderObject(resource); 161b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 162b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam HashMap<RenderObject*, SVGResources*>::iterator end = cache->m_cache.end(); 163b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam for (HashMap<RenderObject*, SVGResources*>::iterator it = cache->m_cache.begin(); it != end; ++it) 164b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam it->second->resourceDestroyed(resource); 165b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam} 166b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 167b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam} 168b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 169b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam#endif 170b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam