• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 blink {
44 
45 RenderLayerFilterInfoMap* RenderLayerFilterInfo::s_filterMap = 0;
46 
filterInfoForRenderLayer(const RenderLayer * layer)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 
createFilterInfoForRenderLayerIfNeeded(RenderLayer * layer)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 
removeFilterInfoForRenderLayer(RenderLayer * layer)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 
RenderLayerFilterInfo(RenderLayer * layer)89 RenderLayerFilterInfo::RenderLayerFilterInfo(RenderLayer* layer)
90     : m_layer(layer)
91 {
92 }
93 
~RenderLayerFilterInfo()94 RenderLayerFilterInfo::~RenderLayerFilterInfo()
95 {
96     removeReferenceFilterClients();
97 }
98 
setRenderer(PassRefPtr<FilterEffectRenderer> renderer)99 void RenderLayerFilterInfo::setRenderer(PassRefPtr<FilterEffectRenderer> renderer)
100 {
101     m_renderer = renderer;
102 }
103 
notifyFinished(Resource *)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->setShouldDoFullPaintInvalidation(true);
113 }
114 
updateReferenceFilterClients(const FilterOperations & operations)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 paint invalidation 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 
removeReferenceFilterClients()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 blink
161 
162