Replace WTF::move with WTFMove
[WebKit-https.git] / Source / WebCore / css / CSSFilterImageValue.cpp
1 /*
2  * Copyright (C) 2013 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  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER "AS IS" AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
17  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
18  * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
21  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
22  * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
23  * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24  * SUCH DAMAGE.
25  */
26
27 #include "config.h"
28 #include "CSSFilterImageValue.h"
29
30 #include "CSSImageValue.h"
31 #include "CachedImage.h"
32 #include "CachedResourceLoader.h"
33 #include "CrossfadeGeneratedImage.h"
34 #include "FilterEffectRenderer.h"
35 #include "ImageBuffer.h"
36 #include "RenderElement.h"
37 #include "StyleCachedImage.h"
38 #include "StyleGeneratedImage.h"
39 #include "StyleResolver.h"
40 #include <wtf/text/StringBuilder.h>
41
42 namespace WebCore {
43
44 CSSFilterImageValue::~CSSFilterImageValue()
45 {
46     if (m_cachedImage)
47         m_cachedImage->removeClient(&m_filterSubimageObserver);
48 }
49
50 String CSSFilterImageValue::customCSSText() const
51 {
52     StringBuilder result;
53     result.appendLiteral("filter(");
54     result.append(m_imageValue->cssText());
55     result.appendLiteral(", ");
56     result.append(m_filterValue->cssText());
57     result.append(')');
58     return result.toString();
59 }
60
61 FloatSize CSSFilterImageValue::fixedSize(const RenderElement* renderer)
62 {
63     // FIXME: Skip Content Security Policy check when filter is applied to an element in a user agent shadow tree.
64     // See <https://bugs.webkit.org/show_bug.cgi?id=146663>.
65     ResourceLoaderOptions options = CachedResourceLoader::defaultCachedResourceOptions();
66
67     CachedResourceLoader& cachedResourceLoader = renderer->document().cachedResourceLoader();
68     CachedImage* cachedImage = cachedImageForCSSValue(m_imageValue.get(), cachedResourceLoader, options);
69
70     if (!cachedImage)
71         return FloatSize();
72
73     return cachedImage->imageForRenderer(renderer)->size();
74 }
75
76 bool CSSFilterImageValue::isPending() const
77 {
78     return CSSImageGeneratorValue::subimageIsPending(m_imageValue.get());
79 }
80
81 bool CSSFilterImageValue::knownToBeOpaque(const RenderElement*) const
82 {
83     return false;
84 }
85
86 void CSSFilterImageValue::loadSubimages(CachedResourceLoader& cachedResourceLoader, const ResourceLoaderOptions& options)
87 {
88     CachedResourceHandle<CachedImage> oldCachedImage = m_cachedImage;
89
90     m_cachedImage = CSSImageGeneratorValue::cachedImageForCSSValue(m_imageValue.get(), cachedResourceLoader, options);
91
92     if (m_cachedImage != oldCachedImage) {
93         if (oldCachedImage)
94             oldCachedImage->removeClient(&m_filterSubimageObserver);
95         if (m_cachedImage)
96             m_cachedImage->addClient(&m_filterSubimageObserver);
97     }
98
99     m_filterSubimageObserver.setReady(true);
100 }
101
102 RefPtr<Image> CSSFilterImageValue::image(RenderElement* renderer, const FloatSize& size)
103 {
104     if (size.isEmpty())
105         return nullptr;
106
107     // FIXME: Skip Content Security Policy check when filter is applied to an element in a user agent shadow tree.
108     // See <https://bugs.webkit.org/show_bug.cgi?id=146663>.
109     ResourceLoaderOptions options = CachedResourceLoader::defaultCachedResourceOptions();
110
111     CachedResourceLoader& cachedResourceLoader = renderer->document().cachedResourceLoader();
112     CachedImage* cachedImage = cachedImageForCSSValue(m_imageValue.get(), cachedResourceLoader, options);
113
114     if (!cachedImage)
115         return Image::nullImage();
116
117     Image* image = cachedImage->imageForRenderer(renderer);
118
119     if (!image)
120         return Image::nullImage();
121
122     // Transform Image into ImageBuffer.
123     // FIXME (149424): This buffer should not be unconditionally unaccelerated.
124     std::unique_ptr<ImageBuffer> texture = ImageBuffer::create(size, Unaccelerated);
125     if (!texture)
126         return Image::nullImage();
127
128     FloatRect imageRect = FloatRect(FloatPoint(), size);
129     texture->context().drawImage(*image, imageRect);
130
131     RefPtr<FilterEffectRenderer> filterRenderer = FilterEffectRenderer::create();
132     filterRenderer->setSourceImage(WTFMove(texture));
133     filterRenderer->setSourceImageRect(imageRect);
134     filterRenderer->setFilterRegion(imageRect);
135     if (!filterRenderer->build(renderer, m_filterOperations, FilterFunction))
136         return Image::nullImage();
137     filterRenderer->apply();
138
139     m_generatedImage = filterRenderer->output()->copyImage();
140
141     return m_generatedImage.release();
142 }
143
144 void CSSFilterImageValue::filterImageChanged(const IntRect&)
145 {
146     for (auto it = clients().begin(), end = clients().end(); it != end; ++it)
147         it->key->imageChanged(static_cast<WrappedImagePtr>(this));
148 }
149
150 void CSSFilterImageValue::createFilterOperations(StyleResolver* resolver)
151 {
152     m_filterOperations.clear();
153     if (m_filterValue)
154         resolver->createFilterOperations(*m_filterValue, m_filterOperations);
155 }
156
157 void CSSFilterImageValue::FilterSubimageObserverProxy::imageChanged(CachedImage*, const IntRect* rect)
158 {
159     if (m_ready)
160         m_ownerValue->filterImageChanged(*rect);
161 }
162
163 bool CSSFilterImageValue::traverseSubresources(const std::function<bool (const CachedResource&)>& handler) const
164 {
165     if (!m_cachedImage)
166         return false;
167     return handler(*m_cachedImage);
168 }
169
170 bool CSSFilterImageValue::equals(const CSSFilterImageValue& other) const
171 {
172     return equalInputImages(other) && compareCSSValuePtr(m_filterValue, other.m_filterValue);
173 }
174
175 bool CSSFilterImageValue::equalInputImages(const CSSFilterImageValue& other) const
176 {
177     return compareCSSValuePtr(m_imageValue, other.m_imageValue);
178 }
179
180 } // namespace WebCore