Home | History | Annotate | Download | only in rendering
      1 /*
      2  * Copyright (C) 2012 Adobe Systems Incorporated. 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
      6  * are met:
      7  *
      8  * 1. Redistributions of source code must retain the above
      9  *    copyright notice, this list of conditions and the following
     10  *    disclaimer.
     11  * 2. Redistributions in binary form must reproduce the above
     12  *    copyright notice, this list of conditions and the following
     13  *    disclaimer in the documentation and/or other materials
     14  *    provided with the distribution.
     15  *
     16  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER "AS IS" AND ANY
     17  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     19  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
     20  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
     21  * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     22  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
     23  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     24  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
     25  * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
     26  * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     27  * SUCH DAMAGE.
     28  */
     29 
     30 #include "config.h"
     31 
     32 #include "core/rendering/RenderLayerFilterInfo.h"
     33 
     34 #include "core/fetch/DocumentResourceReference.h"
     35 #include "core/rendering/FilterEffectRenderer.h"
     36 #include "core/rendering/RenderLayer.h"
     37 #include "core/rendering/svg/ReferenceFilterBuilder.h"
     38 #include "core/rendering/svg/RenderSVGResourceContainer.h"
     39 #include "core/svg/SVGFilterElement.h"
     40 #include "core/svg/SVGFilterPrimitiveStandardAttributes.h"
     41 #include "core/svg/graphics/filters/SVGFilter.h"
     42 
     43 namespace WebCore {
     44 
     45 RenderLayerFilterInfoMap* RenderLayerFilterInfo::s_filterMap = 0;
     46 
     47 RenderLayerFilterInfo* RenderLayerFilterInfo::filterInfoForRenderLayer(const RenderLayer* layer)
     48 {
     49     if (!s_filterMap)
     50         return 0;
     51     RenderLayerFilterInfoMap::iterator iter = s_filterMap->find(layer);
     52     return (iter != s_filterMap->end()) ? iter->value : 0;
     53 }
     54 
     55 RenderLayerFilterInfo* RenderLayerFilterInfo::createFilterInfoForRenderLayerIfNeeded(RenderLayer* layer)
     56 {
     57     if (!s_filterMap)
     58         s_filterMap = new RenderLayerFilterInfoMap();
     59 
     60     RenderLayerFilterInfoMap::iterator iter = s_filterMap->find(layer);
     61     if (iter != s_filterMap->end()) {
     62         ASSERT(layer->hasFilterInfo());
     63         return iter->value;
     64     }
     65 
     66     RenderLayerFilterInfo* filter = new RenderLayerFilterInfo(layer);
     67     s_filterMap->set(layer, filter);
     68     layer->setHasFilterInfo(true);
     69     return filter;
     70 }
     71 
     72 void RenderLayerFilterInfo::removeFilterInfoForRenderLayer(RenderLayer* layer)
     73 {
     74     if (!s_filterMap)
     75         return;
     76     RenderLayerFilterInfo* filter = s_filterMap->take(layer);
     77     if (s_filterMap->isEmpty()) {
     78         delete s_filterMap;
     79         s_filterMap = 0;
     80     }
     81     if (!filter) {
     82         ASSERT(!layer->hasFilterInfo());
     83         return;
     84     }
     85     layer->setHasFilterInfo(false);
     86     delete filter;
     87 }
     88 
     89 RenderLayerFilterInfo::RenderLayerFilterInfo(RenderLayer* layer)
     90     : m_layer(layer)
     91 {
     92 }
     93 
     94 RenderLayerFilterInfo::~RenderLayerFilterInfo()
     95 {
     96     removeReferenceFilterClients();
     97 }
     98 
     99 void RenderLayerFilterInfo::setRenderer(PassRefPtr<FilterEffectRenderer> renderer)
    100 {
    101     m_renderer = renderer;
    102 }
    103 
    104 void RenderLayerFilterInfo::notifyFinished(Resource*)
    105 {
    106     RenderObject* renderer = m_layer->renderer();
    107     // FIXME: This caller of scheduleSVGFilterLayerUpdateHack() is not correct. It's using the layer update
    108     // system to trigger a RenderLayer to go through the filter updating logic, but that might not
    109     // even happen if this element is style sharing and RenderObject::setStyle() returns early.
    110     // Filters need to find a better way to hook into the system.
    111     toElement(renderer->node())->scheduleSVGFilterLayerUpdateHack();
    112     renderer->paintInvalidationForWholeRenderer();
    113 }
    114 
    115 void RenderLayerFilterInfo::updateReferenceFilterClients(const FilterOperations& operations)
    116 {
    117     removeReferenceFilterClients();
    118     for (size_t i = 0; i < operations.size(); ++i) {
    119         RefPtr<FilterOperation> filterOperation = operations.operations().at(i);
    120         if (filterOperation->type() != FilterOperation::REFERENCE)
    121             continue;
    122         ReferenceFilterOperation* referenceFilterOperation = toReferenceFilterOperation(filterOperation.get());
    123         DocumentResourceReference* documentReference = ReferenceFilterBuilder::documentResourceReference(referenceFilterOperation);
    124         DocumentResource* cachedSVGDocument = documentReference ? documentReference->document() : 0;
    125 
    126         if (cachedSVGDocument) {
    127             // Reference is external; wait for notifyFinished().
    128             cachedSVGDocument->addClient(this);
    129             m_externalSVGReferences.append(cachedSVGDocument);
    130         } else {
    131             // Reference is internal; add layer as a client so we can trigger
    132             // filter repaint on SVG attribute change.
    133             Element* filter = m_layer->renderer()->node()->document().getElementById(referenceFilterOperation->fragment());
    134             if (!isSVGFilterElement(filter))
    135                 continue;
    136             if (filter->renderer())
    137                 toRenderSVGResourceContainer(filter->renderer())->addClientRenderLayer(m_layer);
    138             else
    139                 toSVGFilterElement(filter)->addClient(m_layer->renderer()->node());
    140             m_internalSVGReferences.append(filter);
    141         }
    142     }
    143 }
    144 
    145 void RenderLayerFilterInfo::removeReferenceFilterClients()
    146 {
    147     for (size_t i = 0; i < m_externalSVGReferences.size(); ++i)
    148         m_externalSVGReferences.at(i)->removeClient(this);
    149     m_externalSVGReferences.clear();
    150     for (size_t i = 0; i < m_internalSVGReferences.size(); ++i) {
    151         Element* filter = m_internalSVGReferences.at(i).get();
    152         if (filter->renderer())
    153             toRenderSVGResourceContainer(filter->renderer())->removeClientRenderLayer(m_layer);
    154         else
    155             toSVGFilterElement(filter)->removeClient(m_layer->renderer()->node());
    156     }
    157     m_internalSVGReferences.clear();
    158 }
    159 
    160 } // namespace WebCore
    161 
    162