blob: fb899557175563b955d3817874ed4b778c0247c5 [file] [log] [blame]
hyatt@apple.com805aaf42008-04-12 03:24:45 +00001/*
akling@apple.comf7adfcf2013-05-10 17:34:36 +00002 * Copyright (C) 2008, 2011, 2012, 2013 Apple Inc. All rights reserved.
krit@webkit.orgc18645d2013-08-15 21:29:26 +00003 * Copyright (C) 2013 Adobe Systems Incorporated. All rights reserved.
hyatt@apple.com805aaf42008-04-12 03:24:45 +00004 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 *
mjs@apple.com92047332014-03-15 04:08:27 +000014 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
hyatt@apple.com805aaf42008-04-12 03:24:45 +000015 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
mjs@apple.com92047332014-03-15 04:08:27 +000017 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
hyatt@apple.com805aaf42008-04-12 03:24:45 +000018 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
21 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
22 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
apavlov@chromium.orgf684aec2011-10-19 13:31:03 +000024 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
hyatt@apple.com805aaf42008-04-12 03:24:45 +000025 */
26
27#include "config.h"
28#include "CSSImageGeneratorValue.h"
29
andreas.kling@nokia.com30778ea2011-11-08 17:33:07 +000030#include "CSSCanvasValue.h"
31#include "CSSCrossfadeValue.h"
krit@webkit.orgc18645d2013-08-15 21:29:26 +000032#include "CSSFilterImageValue.h"
andreas.kling@nokia.com30778ea2011-11-08 17:33:07 +000033#include "CSSGradientValue.h"
krit@webkit.orgc18645d2013-08-15 21:29:26 +000034#include "CSSImageValue.h"
darin@apple.com044e7222013-12-13 06:52:57 +000035#include "GeneratedImage.h"
darin@apple.com8cdf7122013-09-30 02:40:50 +000036#include "RenderElement.h"
krit@webkit.orgc18645d2013-08-15 21:29:26 +000037#include "StyleCachedImage.h"
hyatt@apple.com805aaf42008-04-12 03:24:45 +000038
39namespace WebCore {
40
andersca@apple.com8ef4e622014-06-02 23:44:48 +000041static const auto timeToKeepCachedGeneratedImages = std::chrono::seconds { 3 };
akling@apple.comf7adfcf2013-05-10 17:34:36 +000042
andreas.kling@nokia.com5fd2a712011-11-07 21:19:45 +000043CSSImageGeneratorValue::CSSImageGeneratorValue(ClassType classType)
44 : CSSValue(classType)
hyatt@apple.com18d8fbf2008-04-13 08:16:23 +000045{
hyatt@apple.com18d8fbf2008-04-13 08:16:23 +000046}
47
hyatt@apple.com805aaf42008-04-12 03:24:45 +000048CSSImageGeneratorValue::~CSSImageGeneratorValue()
49{
hyatt@apple.com805aaf42008-04-12 03:24:45 +000050}
51
darin@apple.com8cdf7122013-09-30 02:40:50 +000052void CSSImageGeneratorValue::addClient(RenderElement* renderer)
hyatt@apple.com805aaf42008-04-12 03:24:45 +000053{
zimmermann@webkit.org57e4d0f2011-11-08 12:29:38 +000054 ASSERT(renderer);
darin@apple.com41cef872013-12-15 16:40:48 +000055 if (m_clients.isEmpty())
56 ref();
akling@apple.comf7adfcf2013-05-10 17:34:36 +000057 m_clients.add(renderer);
hyatt@apple.com805aaf42008-04-12 03:24:45 +000058}
59
darin@apple.com8cdf7122013-09-30 02:40:50 +000060void CSSImageGeneratorValue::removeClient(RenderElement* renderer)
hyatt@apple.com805aaf42008-04-12 03:24:45 +000061{
zimmermann@webkit.org57e4d0f2011-11-08 12:29:38 +000062 ASSERT(renderer);
darin@apple.com41cef872013-12-15 16:40:48 +000063 ASSERT(m_clients.contains(renderer));
64 if (m_clients.remove(renderer) && m_clients.isEmpty())
65 deref();
hyatt@apple.com805aaf42008-04-12 03:24:45 +000066}
67
zalan@apple.comfacdea72014-04-02 14:18:58 +000068GeneratedImage* CSSImageGeneratorValue::cachedImageForSize(FloatSize size)
hyatt@apple.com805aaf42008-04-12 03:24:45 +000069{
zimmermann@webkit.org57e4d0f2011-11-08 12:29:38 +000070 if (size.isEmpty())
darin@apple.com41cef872013-12-15 16:40:48 +000071 return nullptr;
zimmermann@webkit.org57e4d0f2011-11-08 12:29:38 +000072
akling@apple.comf7adfcf2013-05-10 17:34:36 +000073 CachedGeneratedImage* cachedGeneratedImage = m_images.get(size);
74 if (!cachedGeneratedImage)
darin@apple.com41cef872013-12-15 16:40:48 +000075 return nullptr;
akling@apple.comf7adfcf2013-05-10 17:34:36 +000076
77 cachedGeneratedImage->puntEvictionTimer();
78 return cachedGeneratedImage->image();
hyatt@apple.com805aaf42008-04-12 03:24:45 +000079}
80
zalan@apple.comfacdea72014-04-02 14:18:58 +000081void CSSImageGeneratorValue::saveCachedImageForSize(FloatSize size, PassRefPtr<GeneratedImage> image)
hyatt@apple.com805aaf42008-04-12 03:24:45 +000082{
akling@apple.comf7adfcf2013-05-10 17:34:36 +000083 ASSERT(!m_images.contains(size));
darin@apple.com044e7222013-12-13 06:52:57 +000084 m_images.add(size, std::make_unique<CachedGeneratedImage>(*this, size, image));
akling@apple.comf7adfcf2013-05-10 17:34:36 +000085}
86
zalan@apple.comfacdea72014-04-02 14:18:58 +000087void CSSImageGeneratorValue::evictCachedGeneratedImage(FloatSize size)
akling@apple.comf7adfcf2013-05-10 17:34:36 +000088{
89 ASSERT(m_images.contains(size));
90 m_images.remove(size);
91}
92
zalan@apple.comfacdea72014-04-02 14:18:58 +000093CSSImageGeneratorValue::CachedGeneratedImage::CachedGeneratedImage(CSSImageGeneratorValue& owner, FloatSize size, PassRefPtr<GeneratedImage> image)
akling@apple.comf7adfcf2013-05-10 17:34:36 +000094 : m_owner(owner)
95 , m_size(size)
96 , m_image(image)
andersca@apple.com8ef4e622014-06-02 23:44:48 +000097 , m_evictionTimer(this, &CSSImageGeneratorValue::CachedGeneratedImage::evictionTimerFired, timeToKeepCachedGeneratedImages)
akling@apple.comf7adfcf2013-05-10 17:34:36 +000098{
99 m_evictionTimer.restart();
100}
101
andersca@apple.com8ef4e622014-06-02 23:44:48 +0000102void CSSImageGeneratorValue::CachedGeneratedImage::evictionTimerFired()
akling@apple.comf7adfcf2013-05-10 17:34:36 +0000103{
104 // NOTE: This is essentially a "delete this", the object is no longer valid after this line.
105 m_owner.evictCachedGeneratedImage(m_size);
hyatt@apple.com805aaf42008-04-12 03:24:45 +0000106}
107
zalan@apple.comfacdea72014-04-02 14:18:58 +0000108PassRefPtr<Image> CSSImageGeneratorValue::image(RenderElement* renderer, const FloatSize& size)
andreas.kling@nokia.com30778ea2011-11-08 17:33:07 +0000109{
110 switch (classType()) {
111 case CanvasClass:
cdumez@apple.com7e1bcb22014-10-03 23:17:00 +0000112 return downcast<CSSCanvasValue>(*this).image(renderer, size);
andreas.kling@nokia.com30778ea2011-11-08 17:33:07 +0000113 case CrossfadeClass:
cdumez@apple.com7e1bcb22014-10-03 23:17:00 +0000114 return downcast<CSSCrossfadeValue>(*this).image(renderer, size);
krit@webkit.orgc18645d2013-08-15 21:29:26 +0000115 case FilterImageClass:
cdumez@apple.com7e1bcb22014-10-03 23:17:00 +0000116 return downcast<CSSFilterImageValue>(*this).image(renderer, size);
andreas.kling@nokia.com30778ea2011-11-08 17:33:07 +0000117 case LinearGradientClass:
cdumez@apple.com7e1bcb22014-10-03 23:17:00 +0000118 return downcast<CSSLinearGradientValue>(*this).image(renderer, size);
andreas.kling@nokia.com30778ea2011-11-08 17:33:07 +0000119 case RadialGradientClass:
cdumez@apple.com7e1bcb22014-10-03 23:17:00 +0000120 return downcast<CSSRadialGradientValue>(*this).image(renderer, size);
andreas.kling@nokia.com30778ea2011-11-08 17:33:07 +0000121 default:
122 ASSERT_NOT_REACHED();
123 }
darin@apple.com41cef872013-12-15 16:40:48 +0000124 return nullptr;
andreas.kling@nokia.com30778ea2011-11-08 17:33:07 +0000125}
126
127bool CSSImageGeneratorValue::isFixedSize() const
128{
129 switch (classType()) {
130 case CanvasClass:
cdumez@apple.com7e1bcb22014-10-03 23:17:00 +0000131 return downcast<CSSCanvasValue>(*this).isFixedSize();
andreas.kling@nokia.com30778ea2011-11-08 17:33:07 +0000132 case CrossfadeClass:
cdumez@apple.com7e1bcb22014-10-03 23:17:00 +0000133 return downcast<CSSCrossfadeValue>(*this).isFixedSize();
krit@webkit.orgc18645d2013-08-15 21:29:26 +0000134 case FilterImageClass:
cdumez@apple.com7e1bcb22014-10-03 23:17:00 +0000135 return downcast<CSSFilterImageValue>(*this).isFixedSize();
andreas.kling@nokia.com30778ea2011-11-08 17:33:07 +0000136 case LinearGradientClass:
cdumez@apple.com7e1bcb22014-10-03 23:17:00 +0000137 return downcast<CSSLinearGradientValue>(*this).isFixedSize();
andreas.kling@nokia.com30778ea2011-11-08 17:33:07 +0000138 case RadialGradientClass:
cdumez@apple.com7e1bcb22014-10-03 23:17:00 +0000139 return downcast<CSSRadialGradientValue>(*this).isFixedSize();
andreas.kling@nokia.com30778ea2011-11-08 17:33:07 +0000140 default:
141 ASSERT_NOT_REACHED();
142 }
143 return false;
144}
145
zalan@apple.comfacdea72014-04-02 14:18:58 +0000146FloatSize CSSImageGeneratorValue::fixedSize(const RenderElement* renderer)
andreas.kling@nokia.com30778ea2011-11-08 17:33:07 +0000147{
148 switch (classType()) {
149 case CanvasClass:
cdumez@apple.com7e1bcb22014-10-03 23:17:00 +0000150 return downcast<CSSCanvasValue>(*this).fixedSize(renderer);
andreas.kling@nokia.com30778ea2011-11-08 17:33:07 +0000151 case CrossfadeClass:
cdumez@apple.com7e1bcb22014-10-03 23:17:00 +0000152 return downcast<CSSCrossfadeValue>(*this).fixedSize(renderer);
krit@webkit.orgc18645d2013-08-15 21:29:26 +0000153 case FilterImageClass:
cdumez@apple.com7e1bcb22014-10-03 23:17:00 +0000154 return downcast<CSSFilterImageValue>(*this).fixedSize(renderer);
andreas.kling@nokia.com30778ea2011-11-08 17:33:07 +0000155 case LinearGradientClass:
cdumez@apple.com7e1bcb22014-10-03 23:17:00 +0000156 return downcast<CSSLinearGradientValue>(*this).fixedSize(renderer);
andreas.kling@nokia.com30778ea2011-11-08 17:33:07 +0000157 case RadialGradientClass:
cdumez@apple.com7e1bcb22014-10-03 23:17:00 +0000158 return downcast<CSSRadialGradientValue>(*this).fixedSize(renderer);
andreas.kling@nokia.com30778ea2011-11-08 17:33:07 +0000159 default:
160 ASSERT_NOT_REACHED();
161 }
zalan@apple.comfacdea72014-04-02 14:18:58 +0000162 return FloatSize();
andreas.kling@nokia.com30778ea2011-11-08 17:33:07 +0000163}
164
timothy_horton@apple.com37b17642011-11-17 01:28:25 +0000165bool CSSImageGeneratorValue::isPending() const
166{
167 switch (classType()) {
168 case CrossfadeClass:
cdumez@apple.com7e1bcb22014-10-03 23:17:00 +0000169 return downcast<CSSCrossfadeValue>(*this).isPending();
timothy_horton@apple.com37b17642011-11-17 01:28:25 +0000170 case CanvasClass:
cdumez@apple.com7e1bcb22014-10-03 23:17:00 +0000171 return downcast<CSSCanvasValue>(*this).isPending();
krit@webkit.orgc18645d2013-08-15 21:29:26 +0000172 case FilterImageClass:
cdumez@apple.com7e1bcb22014-10-03 23:17:00 +0000173 return downcast<CSSFilterImageValue>(*this).isPending();
timothy_horton@apple.com37b17642011-11-17 01:28:25 +0000174 case LinearGradientClass:
cdumez@apple.com7e1bcb22014-10-03 23:17:00 +0000175 return downcast<CSSLinearGradientValue>(*this).isPending();
timothy_horton@apple.com37b17642011-11-17 01:28:25 +0000176 case RadialGradientClass:
cdumez@apple.com7e1bcb22014-10-03 23:17:00 +0000177 return downcast<CSSRadialGradientValue>(*this).isPending();
timothy_horton@apple.com37b17642011-11-17 01:28:25 +0000178 default:
179 ASSERT_NOT_REACHED();
180 }
181 return false;
182}
183
darin@apple.com8cdf7122013-09-30 02:40:50 +0000184bool CSSImageGeneratorValue::knownToBeOpaque(const RenderElement* renderer) const
junov@google.comf3d27f22012-11-23 18:43:51 +0000185{
186 switch (classType()) {
187 case CrossfadeClass:
cdumez@apple.com7e1bcb22014-10-03 23:17:00 +0000188 return downcast<CSSCrossfadeValue>(*this).knownToBeOpaque(renderer);
junov@google.comf3d27f22012-11-23 18:43:51 +0000189 case CanvasClass:
pdr@google.comebc67c62013-02-01 21:31:00 +0000190 return false;
krit@webkit.orgc18645d2013-08-15 21:29:26 +0000191 case FilterImageClass:
cdumez@apple.com7e1bcb22014-10-03 23:17:00 +0000192 return downcast<CSSFilterImageValue>(*this).knownToBeOpaque(renderer);
junov@google.comf3d27f22012-11-23 18:43:51 +0000193 case LinearGradientClass:
cdumez@apple.com7e1bcb22014-10-03 23:17:00 +0000194 return downcast<CSSLinearGradientValue>(*this).knownToBeOpaque(renderer);
junov@google.comf3d27f22012-11-23 18:43:51 +0000195 case RadialGradientClass:
cdumez@apple.com7e1bcb22014-10-03 23:17:00 +0000196 return downcast<CSSRadialGradientValue>(*this).knownToBeOpaque(renderer);
junov@google.comf3d27f22012-11-23 18:43:51 +0000197 default:
198 ASSERT_NOT_REACHED();
199 }
pdr@google.comebc67c62013-02-01 21:31:00 +0000200 return false;
junov@google.comf3d27f22012-11-23 18:43:51 +0000201}
202
timothy_horton@apple.com37b17642011-11-17 01:28:25 +0000203void CSSImageGeneratorValue::loadSubimages(CachedResourceLoader* cachedResourceLoader)
204{
205 switch (classType()) {
206 case CrossfadeClass:
cdumez@apple.com7e1bcb22014-10-03 23:17:00 +0000207 downcast<CSSCrossfadeValue>(*this).loadSubimages(cachedResourceLoader);
timothy_horton@apple.com37b17642011-11-17 01:28:25 +0000208 break;
209 case CanvasClass:
cdumez@apple.com7e1bcb22014-10-03 23:17:00 +0000210 downcast<CSSCanvasValue>(*this).loadSubimages(cachedResourceLoader);
timothy_horton@apple.com37b17642011-11-17 01:28:25 +0000211 break;
krit@webkit.orgc18645d2013-08-15 21:29:26 +0000212 case FilterImageClass:
cdumez@apple.com7e1bcb22014-10-03 23:17:00 +0000213 downcast<CSSFilterImageValue>(*this).loadSubimages(cachedResourceLoader);
krit@webkit.orgc18645d2013-08-15 21:29:26 +0000214 break;
timothy_horton@apple.com37b17642011-11-17 01:28:25 +0000215 case LinearGradientClass:
cdumez@apple.com7e1bcb22014-10-03 23:17:00 +0000216 downcast<CSSLinearGradientValue>(*this).loadSubimages(cachedResourceLoader);
timothy_horton@apple.com37b17642011-11-17 01:28:25 +0000217 break;
218 case RadialGradientClass:
cdumez@apple.com7e1bcb22014-10-03 23:17:00 +0000219 downcast<CSSRadialGradientValue>(*this).loadSubimages(cachedResourceLoader);
timothy_horton@apple.com37b17642011-11-17 01:28:25 +0000220 break;
221 default:
222 ASSERT_NOT_REACHED();
223 }
224}
225
krit@webkit.orgc18645d2013-08-15 21:29:26 +0000226bool CSSImageGeneratorValue::subimageIsPending(CSSValue* value)
227{
cdumez@apple.com7e1bcb22014-10-03 23:17:00 +0000228 if (is<CSSImageValue>(*value))
229 return downcast<CSSImageValue>(*value).cachedOrPendingImage()->isPendingImage();
krit@webkit.orgc18645d2013-08-15 21:29:26 +0000230
cdumez@apple.com7e1bcb22014-10-03 23:17:00 +0000231 if (is<CSSImageGeneratorValue>(*value))
232 return downcast<CSSImageGeneratorValue>(*value).isPending();
krit@webkit.orgc18645d2013-08-15 21:29:26 +0000233
cdumez@apple.com7e1bcb22014-10-03 23:17:00 +0000234 if (is<CSSPrimitiveValue>(*value) && downcast<CSSPrimitiveValue>(*value).getValueID() == CSSValueNone)
krit@webkit.orgc18645d2013-08-15 21:29:26 +0000235 return false;
236
237 ASSERT_NOT_REACHED();
238
239 return false;
240}
241
242CachedImage* CSSImageGeneratorValue::cachedImageForCSSValue(CSSValue* value, CachedResourceLoader* cachedResourceLoader)
243{
244 if (!value)
darin@apple.com044e7222013-12-13 06:52:57 +0000245 return nullptr;
krit@webkit.orgc18645d2013-08-15 21:29:26 +0000246
cdumez@apple.com7e1bcb22014-10-03 23:17:00 +0000247 if (is<CSSImageValue>(*value)) {
248 StyleCachedImage* styleCachedImage = downcast<CSSImageValue>(*value).cachedImage(cachedResourceLoader);
krit@webkit.orgc18645d2013-08-15 21:29:26 +0000249 if (!styleCachedImage)
darin@apple.com044e7222013-12-13 06:52:57 +0000250 return nullptr;
krit@webkit.orgc18645d2013-08-15 21:29:26 +0000251
252 return styleCachedImage->cachedImage();
253 }
254
cdumez@apple.com7e1bcb22014-10-03 23:17:00 +0000255 if (is<CSSImageGeneratorValue>(*value)) {
256 downcast<CSSImageGeneratorValue>(*value).loadSubimages(cachedResourceLoader);
krit@webkit.orgc18645d2013-08-15 21:29:26 +0000257 // FIXME: Handle CSSImageGeneratorValue (and thus cross-fades with gradients and canvas).
darin@apple.com044e7222013-12-13 06:52:57 +0000258 return nullptr;
krit@webkit.orgc18645d2013-08-15 21:29:26 +0000259 }
260
cdumez@apple.com7e1bcb22014-10-03 23:17:00 +0000261 if (is<CSSPrimitiveValue>(*value) && downcast<CSSPrimitiveValue>(*value).getValueID() == CSSValueNone)
darin@apple.com044e7222013-12-13 06:52:57 +0000262 return nullptr;
krit@webkit.orgc18645d2013-08-15 21:29:26 +0000263
264 ASSERT_NOT_REACHED();
265
darin@apple.com044e7222013-12-13 06:52:57 +0000266 return nullptr;
krit@webkit.orgc18645d2013-08-15 21:29:26 +0000267}
hyatt@apple.com805aaf42008-04-12 03:24:45 +0000268} // namespace WebCore