OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2004, 2005, 2006, 2007 Nikolas Zimmermann <zimmermann@kde.org> | 2 * Copyright (C) 2004, 2005, 2006, 2007 Nikolas Zimmermann <zimmermann@kde.org> |
3 * Copyright (C) 2004, 2005 Rob Buis <buis@kde.org> | 3 * Copyright (C) 2004, 2005 Rob Buis <buis@kde.org> |
4 * Copyright (C) 2005 Eric Seidel <eric@webkit.org> | 4 * Copyright (C) 2005 Eric Seidel <eric@webkit.org> |
5 * Copyright (C) 2009 Dirk Schulze <krit@webkit.org> | 5 * Copyright (C) 2009 Dirk Schulze <krit@webkit.org> |
6 * Copyright (C) Research In Motion Limited 2010. All rights reserved. | 6 * Copyright (C) Research In Motion Limited 2010. All rights reserved. |
7 * | 7 * |
8 * This library is free software; you can redistribute it and/or | 8 * This library is free software; you can redistribute it and/or |
9 * modify it under the terms of the GNU Library General Public | 9 * modify it under the terms of the GNU Library General Public |
10 * License as published by the Free Software Foundation; either | 10 * License as published by the Free Software Foundation; either |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
50 #include "SourceAlpha.h" | 50 #include "SourceAlpha.h" |
51 #include "SourceGraphic.h" | 51 #include "SourceGraphic.h" |
52 | 52 |
53 #include <wtf/UnusedParam.h> | 53 #include <wtf/UnusedParam.h> |
54 #include <wtf/Vector.h> | 54 #include <wtf/Vector.h> |
55 | 55 |
56 using namespace std; | 56 using namespace std; |
57 | 57 |
58 namespace WebCore { | 58 namespace WebCore { |
59 | 59 |
| 60 class ApplyingFilterEffectGuard { |
| 61 public: |
| 62 ApplyingFilterEffectGuard(FilterData* data) |
| 63 : m_filterData(data) |
| 64 { |
| 65 // The guard must be constructed when the filter is not applying. |
| 66 ASSERT(!m_filterData->isApplying); |
| 67 m_filterData->isApplying = true; |
| 68 } |
| 69 |
| 70 ~ApplyingFilterEffectGuard() |
| 71 { |
| 72 ASSERT(m_filterData->isApplying); |
| 73 m_filterData->isApplying = false; |
| 74 } |
| 75 |
| 76 FilterData* m_filterData; |
| 77 }; |
| 78 |
60 RenderSVGResourceType RenderSVGResourceFilter::s_resourceType = FilterResourceTy
pe; | 79 RenderSVGResourceType RenderSVGResourceFilter::s_resourceType = FilterResourceTy
pe; |
61 | 80 |
62 RenderSVGResourceFilter::RenderSVGResourceFilter(SVGFilterElement* node) | 81 RenderSVGResourceFilter::RenderSVGResourceFilter(SVGFilterElement* node) |
63 : RenderSVGResourceContainer(node) | 82 : RenderSVGResourceContainer(node) |
64 { | 83 { |
65 } | 84 } |
66 | 85 |
67 RenderSVGResourceFilter::~RenderSVGResourceFilter() | 86 RenderSVGResourceFilter::~RenderSVGResourceFilter() |
68 { | 87 { |
69 if (m_filter.isEmpty()) | 88 if (m_filter.isEmpty()) |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
146 bool RenderSVGResourceFilter::applyResource(RenderObject* object, RenderStyle*,
GraphicsContext*& context, unsigned short resourceMode) | 165 bool RenderSVGResourceFilter::applyResource(RenderObject* object, RenderStyle*,
GraphicsContext*& context, unsigned short resourceMode) |
147 { | 166 { |
148 ASSERT(object); | 167 ASSERT(object); |
149 ASSERT(context); | 168 ASSERT(context); |
150 ASSERT_UNUSED(resourceMode, resourceMode == ApplyToDefaultMode); | 169 ASSERT_UNUSED(resourceMode, resourceMode == ApplyToDefaultMode); |
151 | 170 |
152 // Returning false here, to avoid drawings onto the context. We just want to | 171 // Returning false here, to avoid drawings onto the context. We just want to |
153 // draw the stored filter output, not the unfiltered object as well. | 172 // draw the stored filter output, not the unfiltered object as well. |
154 if (m_filter.contains(object)) { | 173 if (m_filter.contains(object)) { |
155 FilterData* filterData = m_filter.get(object); | 174 FilterData* filterData = m_filter.get(object); |
156 if (filterData->builded) | 175 if (filterData->isBuilt || filterData->isApplying) |
157 return false; | 176 return false; |
158 | 177 |
159 delete m_filter.take(object); // Oops, have to rebuild, go through norma
l code path | 178 delete m_filter.take(object); // Oops, have to rebuild, go through norma
l code path |
160 } | 179 } |
161 | 180 |
162 OwnPtr<FilterData> filterData(adoptPtr(new FilterData)); | 181 OwnPtr<FilterData> filterData(adoptPtr(new FilterData)); |
163 FloatRect targetBoundingBox = object->objectBoundingBox(); | 182 FloatRect targetBoundingBox = object->objectBoundingBox(); |
164 | 183 |
165 SVGFilterElement* filterElement = static_cast<SVGFilterElement*>(node()); | 184 SVGFilterElement* filterElement = static_cast<SVGFilterElement*>(node()); |
166 filterData->boundaries = SVGLengthContext::resolveRectangle<SVGFilterElement
>(filterElement, filterElement->filterUnits(), targetBoundingBox); | 185 filterData->boundaries = SVGLengthContext::resolveRectangle<SVGFilterElement
>(filterElement, filterElement->filterUnits(), targetBoundingBox); |
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
271 | 290 |
272 FilterData* filterData = m_filter.get(object); | 291 FilterData* filterData = m_filter.get(object); |
273 if (!filterData) | 292 if (!filterData) |
274 return; | 293 return; |
275 | 294 |
276 if (filterData->markedForRemoval) { | 295 if (filterData->markedForRemoval) { |
277 delete m_filter.take(object); | 296 delete m_filter.take(object); |
278 return; | 297 return; |
279 } | 298 } |
280 | 299 |
281 if (!filterData->builded) { | 300 // We have a cycle if we are already applying the data. |
| 301 // This can occur due to FeImage referencing a source that makes use of the
FEImage itself. |
| 302 if (filterData->isApplying) |
| 303 return; |
| 304 |
| 305 if (!filterData->isBuilt) { |
282 if (!filterData->savedContext) { | 306 if (!filterData->savedContext) { |
283 removeClientFromCache(object); | 307 removeClientFromCache(object); |
284 return; | 308 return; |
285 } | 309 } |
286 | 310 |
287 context = filterData->savedContext; | 311 context = filterData->savedContext; |
288 filterData->savedContext = 0; | 312 filterData->savedContext = 0; |
289 } | 313 } |
290 | 314 |
| 315 ApplyingFilterEffectGuard isApplyingGuard(filterData); |
| 316 |
291 FilterEffect* lastEffect = filterData->builder->lastEffect(); | 317 FilterEffect* lastEffect = filterData->builder->lastEffect(); |
292 | 318 |
293 if (lastEffect && !filterData->boundaries.isEmpty() && !lastEffect->filterPr
imitiveSubregion().isEmpty()) { | 319 if (lastEffect && !filterData->boundaries.isEmpty() && !lastEffect->filterPr
imitiveSubregion().isEmpty()) { |
294 // This is the real filtering of the object. It just needs to be called
on the | 320 // This is the real filtering of the object. It just needs to be called
on the |
295 // initial filtering process. We just take the stored filter result on a | 321 // initial filtering process. We just take the stored filter result on a |
296 // second drawing. | 322 // second drawing. |
297 if (!filterData->builded) | 323 if (!filterData->isBuilt) |
298 filterData->filter->setSourceImage(filterData->sourceGraphicBuffer.r
elease()); | 324 filterData->filter->setSourceImage(filterData->sourceGraphicBuffer.r
elease()); |
299 | 325 |
300 // Always true if filterData is just built (filterData->builded is false
). | 326 // Always true if filterData is just built (filterData->isBuilt is false
). |
301 if (!lastEffect->hasResult()) { | 327 if (!lastEffect->hasResult()) { |
302 lastEffect->apply(); | 328 lastEffect->apply(); |
303 lastEffect->correctFilterResultIfNeeded(); | 329 lastEffect->correctFilterResultIfNeeded(); |
304 #if !USE(CG) | 330 #if !USE(CG) |
305 ImageBuffer* resultImage = lastEffect->asImageBuffer(); | 331 ImageBuffer* resultImage = lastEffect->asImageBuffer(); |
306 if (resultImage) | 332 if (resultImage) |
307 resultImage->transformColorSpace(lastEffect->colorSpace(), Color
SpaceDeviceRGB); | 333 resultImage->transformColorSpace(lastEffect->colorSpace(), Color
SpaceDeviceRGB); |
308 #endif | 334 #endif |
309 } | 335 } |
310 filterData->builded = true; | 336 filterData->isBuilt = true; |
311 | 337 |
312 ImageBuffer* resultImage = lastEffect->asImageBuffer(); | 338 ImageBuffer* resultImage = lastEffect->asImageBuffer(); |
313 if (resultImage) { | 339 if (resultImage) { |
314 context->concatCTM(filterData->shearFreeAbsoluteTransform.inverse())
; | 340 context->concatCTM(filterData->shearFreeAbsoluteTransform.inverse())
; |
315 | 341 |
316 context->scale(FloatSize(1 / filterData->filter->filterResolution().
width(), 1 / filterData->filter->filterResolution().height())); | 342 context->scale(FloatSize(1 / filterData->filter->filterResolution().
width(), 1 / filterData->filter->filterResolution().height())); |
317 context->drawImageBuffer(resultImage, object->style()->colorSpace(),
lastEffect->absolutePaintRect()); | 343 context->drawImageBuffer(resultImage, object->style()->colorSpace(),
lastEffect->absolutePaintRect()); |
318 context->scale(filterData->filter->filterResolution()); | 344 context->scale(filterData->filter->filterResolution()); |
319 | 345 |
320 context->concatCTM(filterData->shearFreeAbsoluteTransform); | 346 context->concatCTM(filterData->shearFreeAbsoluteTransform); |
(...skipping 11 matching lines...) Expand all Loading... |
332 } | 358 } |
333 | 359 |
334 void RenderSVGResourceFilter::primitiveAttributeChanged(RenderObject* object, co
nst QualifiedName& attribute) | 360 void RenderSVGResourceFilter::primitiveAttributeChanged(RenderObject* object, co
nst QualifiedName& attribute) |
335 { | 361 { |
336 HashMap<RenderObject*, FilterData*>::iterator it = m_filter.begin(); | 362 HashMap<RenderObject*, FilterData*>::iterator it = m_filter.begin(); |
337 HashMap<RenderObject*, FilterData*>::iterator end = m_filter.end(); | 363 HashMap<RenderObject*, FilterData*>::iterator end = m_filter.end(); |
338 SVGFilterPrimitiveStandardAttributes* primitve = static_cast<SVGFilterPrimit
iveStandardAttributes*>(object->node()); | 364 SVGFilterPrimitiveStandardAttributes* primitve = static_cast<SVGFilterPrimit
iveStandardAttributes*>(object->node()); |
339 | 365 |
340 for (; it != end; ++it) { | 366 for (; it != end; ++it) { |
341 FilterData* filterData = it->second; | 367 FilterData* filterData = it->second; |
342 if (!filterData->builded) | 368 if (!filterData->isBuilt) |
343 continue; | 369 continue; |
344 | 370 |
345 SVGFilterBuilder* builder = filterData->builder.get(); | 371 SVGFilterBuilder* builder = filterData->builder.get(); |
346 FilterEffect* effect = builder->effectByRenderer(object); | 372 FilterEffect* effect = builder->effectByRenderer(object); |
347 if (!effect) | 373 if (!effect) |
348 continue; | 374 continue; |
349 // Since all effects shares the same attribute value, all | 375 // Since all effects shares the same attribute value, all |
350 // or none of them will be changed. | 376 // or none of them will be changed. |
351 if (!primitve->setFilterEffectAttribute(effect, attribute)) | 377 if (!primitve->setFilterEffectAttribute(effect, attribute)) |
352 return; | 378 return; |
353 builder->clearResultsRecursive(effect); | 379 builder->clearResultsRecursive(effect); |
354 | 380 |
355 // Repaint the image on the screen. | 381 // Repaint the image on the screen. |
356 markClientForInvalidation(it->first, RepaintInvalidation); | 382 markClientForInvalidation(it->first, RepaintInvalidation); |
357 } | 383 } |
358 } | 384 } |
359 | 385 |
360 } | 386 } |
361 #endif | 387 #endif |
OLD | NEW |