Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(47)

Side by Side Diff: Source/WebCore/rendering/svg/RenderSVGResourceFilter.cpp

Issue 11293229: Merge 132856 (Closed) Base URL: http://svn.webkit.org/repository/webkit/branches/chromium/1271/
Patch Set: Created 8 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
79 RenderSVGResourceType RenderSVGResourceFilter::s_resourceType = FilterResourceTy pe; 60 RenderSVGResourceType RenderSVGResourceFilter::s_resourceType = FilterResourceTy pe;
80 61
81 RenderSVGResourceFilter::RenderSVGResourceFilter(SVGFilterElement* node) 62 RenderSVGResourceFilter::RenderSVGResourceFilter(SVGFilterElement* node)
82 : RenderSVGResourceContainer(node) 63 : RenderSVGResourceContainer(node)
83 { 64 {
84 } 65 }
85 66
86 RenderSVGResourceFilter::~RenderSVGResourceFilter() 67 RenderSVGResourceFilter::~RenderSVGResourceFilter()
87 { 68 {
88 if (m_filter.isEmpty()) 69 if (m_filter.isEmpty())
(...skipping 12 matching lines...) Expand all
101 82
102 markAllClientsForInvalidation(markForInvalidation ? LayoutAndBoundariesInval idation : ParentOnlyInvalidation); 83 markAllClientsForInvalidation(markForInvalidation ? LayoutAndBoundariesInval idation : ParentOnlyInvalidation);
103 } 84 }
104 85
105 void RenderSVGResourceFilter::removeClientFromCache(RenderObject* client, bool m arkForInvalidation) 86 void RenderSVGResourceFilter::removeClientFromCache(RenderObject* client, bool m arkForInvalidation)
106 { 87 {
107 ASSERT(client); 88 ASSERT(client);
108 89
109 if (FilterData* filterData = m_filter.get(client)) { 90 if (FilterData* filterData = m_filter.get(client)) {
110 if (filterData->savedContext) 91 if (filterData->savedContext)
111 filterData->markedForRemoval = true; 92 filterData->state = FilterData::MarkedForRemoval;
112 else 93 else
113 delete m_filter.take(client); 94 delete m_filter.take(client);
114 } 95 }
115 96
116 markClientForInvalidation(client, markForInvalidation ? BoundariesInvalidati on : ParentOnlyInvalidation); 97 markClientForInvalidation(client, markForInvalidation ? BoundariesInvalidati on : ParentOnlyInvalidation);
117 } 98 }
118 99
119 PassRefPtr<SVGFilterBuilder> RenderSVGResourceFilter::buildPrimitives(SVGFilter* filter) 100 PassRefPtr<SVGFilterBuilder> RenderSVGResourceFilter::buildPrimitives(SVGFilter* filter)
120 { 101 {
121 SVGFilterElement* filterElement = static_cast<SVGFilterElement*>(node()); 102 SVGFilterElement* filterElement = static_cast<SVGFilterElement*>(node());
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
161 142
162 return matchesFilterSize; 143 return matchesFilterSize;
163 } 144 }
164 145
165 bool RenderSVGResourceFilter::applyResource(RenderObject* object, RenderStyle*, GraphicsContext*& context, unsigned short resourceMode) 146 bool RenderSVGResourceFilter::applyResource(RenderObject* object, RenderStyle*, GraphicsContext*& context, unsigned short resourceMode)
166 { 147 {
167 ASSERT(object); 148 ASSERT(object);
168 ASSERT(context); 149 ASSERT(context);
169 ASSERT_UNUSED(resourceMode, resourceMode == ApplyToDefaultMode); 150 ASSERT_UNUSED(resourceMode, resourceMode == ApplyToDefaultMode);
170 151
171 // Returning false here, to avoid drawings onto the context. We just want to
172 // draw the stored filter output, not the unfiltered object as well.
173 if (m_filter.contains(object)) { 152 if (m_filter.contains(object)) {
174 FilterData* filterData = m_filter.get(object); 153 FilterData* filterData = m_filter.get(object);
175 if (filterData->isBuilt || filterData->isApplying) 154 if (filterData->state == FilterData::PaintingSource || filterData->state == FilterData::Applying)
176 return false; 155 filterData->state = FilterData::CycleDetected;
177 156 return false; // Already built, or we're in a cycle, or we're marked for removal. Regardless, just do nothing more now.
178 delete m_filter.take(object); // Oops, have to rebuild, go through norma l code path
179 } 157 }
180 158
181 OwnPtr<FilterData> filterData(adoptPtr(new FilterData)); 159 OwnPtr<FilterData> filterData(adoptPtr(new FilterData));
182 FloatRect targetBoundingBox = object->objectBoundingBox(); 160 FloatRect targetBoundingBox = object->objectBoundingBox();
183 161
184 SVGFilterElement* filterElement = static_cast<SVGFilterElement*>(node()); 162 SVGFilterElement* filterElement = static_cast<SVGFilterElement*>(node());
185 filterData->boundaries = SVGLengthContext::resolveRectangle<SVGFilterElement >(filterElement, filterElement->filterUnits(), targetBoundingBox); 163 filterData->boundaries = SVGLengthContext::resolveRectangle<SVGFilterElement >(filterElement, filterElement->filterUnits(), targetBoundingBox);
186 if (filterData->boundaries.isEmpty()) 164 if (filterData->boundaries.isEmpty())
187 return false; 165 return false;
188 166
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
285 void RenderSVGResourceFilter::postApplyResource(RenderObject* object, GraphicsCo ntext*& context, unsigned short resourceMode, const Path*, const RenderSVGShape* ) 263 void RenderSVGResourceFilter::postApplyResource(RenderObject* object, GraphicsCo ntext*& context, unsigned short resourceMode, const Path*, const RenderSVGShape* )
286 { 264 {
287 ASSERT(object); 265 ASSERT(object);
288 ASSERT(context); 266 ASSERT(context);
289 ASSERT_UNUSED(resourceMode, resourceMode == ApplyToDefaultMode); 267 ASSERT_UNUSED(resourceMode, resourceMode == ApplyToDefaultMode);
290 268
291 FilterData* filterData = m_filter.get(object); 269 FilterData* filterData = m_filter.get(object);
292 if (!filterData) 270 if (!filterData)
293 return; 271 return;
294 272
295 if (filterData->markedForRemoval) { 273 switch (filterData->state) {
274 case FilterData::MarkedForRemoval:
296 delete m_filter.take(object); 275 delete m_filter.take(object);
297 return; 276 return;
298 }
299 277
300 // We have a cycle if we are already applying the data. 278 case FilterData::CycleDetected:
301 // This can occur due to FeImage referencing a source that makes use of the FEImage itself. 279 case FilterData::Applying:
302 if (filterData->isApplying) 280 // We have a cycle if we are already applying the data.
281 // This can occur due to FeImage referencing a source that makes use of the FEImage itself.
282 // This is the first place we've hit the cycle, so set the state back to PaintingSource so the return stack
283 // will continue correctly.
284 filterData->state = FilterData::PaintingSource;
303 return; 285 return;
304 286
305 if (!filterData->isBuilt) { 287 case FilterData::PaintingSource:
306 if (!filterData->savedContext) { 288 if (!filterData->savedContext) {
307 removeClientFromCache(object); 289 removeClientFromCache(object);
308 return; 290 return;
309 } 291 }
310 292
311 context = filterData->savedContext; 293 context = filterData->savedContext;
312 filterData->savedContext = 0; 294 filterData->savedContext = 0;
295 break;
296
297 case FilterData::Built: { } // Empty
313 } 298 }
314 299
315 ApplyingFilterEffectGuard isApplyingGuard(filterData);
316
317 FilterEffect* lastEffect = filterData->builder->lastEffect(); 300 FilterEffect* lastEffect = filterData->builder->lastEffect();
318 301
319 if (lastEffect && !filterData->boundaries.isEmpty() && !lastEffect->filterPr imitiveSubregion().isEmpty()) { 302 if (lastEffect && !filterData->boundaries.isEmpty() && !lastEffect->filterPr imitiveSubregion().isEmpty()) {
320 // This is the real filtering of the object. It just needs to be called on the 303 // This is the real filtering of the object. It just needs to be called on the
321 // initial filtering process. We just take the stored filter result on a 304 // initial filtering process. We just take the stored filter result on a
322 // second drawing. 305 // second drawing.
323 if (!filterData->isBuilt) 306 if (filterData->state != FilterData::Built)
324 filterData->filter->setSourceImage(filterData->sourceGraphicBuffer.r elease()); 307 filterData->filter->setSourceImage(filterData->sourceGraphicBuffer.r elease());
325 308
326 // Always true if filterData is just built (filterData->isBuilt is false ). 309 // Always true if filterData is just built (filterData->state == FilterD ata::Built).
327 if (!lastEffect->hasResult()) { 310 if (!lastEffect->hasResult()) {
311 filterData->state = FilterData::Applying;
328 lastEffect->apply(); 312 lastEffect->apply();
329 lastEffect->correctFilterResultIfNeeded(); 313 lastEffect->correctFilterResultIfNeeded();
330 #if !USE(CG) 314 #if !USE(CG)
331 ImageBuffer* resultImage = lastEffect->asImageBuffer(); 315 ImageBuffer* resultImage = lastEffect->asImageBuffer();
332 if (resultImage) 316 if (resultImage)
333 resultImage->transformColorSpace(lastEffect->colorSpace(), Color SpaceDeviceRGB); 317 resultImage->transformColorSpace(lastEffect->colorSpace(), Color SpaceDeviceRGB);
334 #endif 318 #endif
335 } 319 }
336 filterData->isBuilt = true; 320 filterData->state = FilterData::Built;
337 321
338 ImageBuffer* resultImage = lastEffect->asImageBuffer(); 322 ImageBuffer* resultImage = lastEffect->asImageBuffer();
339 if (resultImage) { 323 if (resultImage) {
340 context->concatCTM(filterData->shearFreeAbsoluteTransform.inverse()) ; 324 context->concatCTM(filterData->shearFreeAbsoluteTransform.inverse()) ;
341 325
342 context->scale(FloatSize(1 / filterData->filter->filterResolution(). width(), 1 / filterData->filter->filterResolution().height())); 326 context->scale(FloatSize(1 / filterData->filter->filterResolution(). width(), 1 / filterData->filter->filterResolution().height()));
343 context->drawImageBuffer(resultImage, object->style()->colorSpace(), lastEffect->absolutePaintRect()); 327 context->drawImageBuffer(resultImage, object->style()->colorSpace(), lastEffect->absolutePaintRect());
344 context->scale(filterData->filter->filterResolution()); 328 context->scale(filterData->filter->filterResolution());
345 329
346 context->concatCTM(filterData->shearFreeAbsoluteTransform); 330 context->concatCTM(filterData->shearFreeAbsoluteTransform);
(...skipping 11 matching lines...) Expand all
358 } 342 }
359 343
360 void RenderSVGResourceFilter::primitiveAttributeChanged(RenderObject* object, co nst QualifiedName& attribute) 344 void RenderSVGResourceFilter::primitiveAttributeChanged(RenderObject* object, co nst QualifiedName& attribute)
361 { 345 {
362 HashMap<RenderObject*, FilterData*>::iterator it = m_filter.begin(); 346 HashMap<RenderObject*, FilterData*>::iterator it = m_filter.begin();
363 HashMap<RenderObject*, FilterData*>::iterator end = m_filter.end(); 347 HashMap<RenderObject*, FilterData*>::iterator end = m_filter.end();
364 SVGFilterPrimitiveStandardAttributes* primitve = static_cast<SVGFilterPrimit iveStandardAttributes*>(object->node()); 348 SVGFilterPrimitiveStandardAttributes* primitve = static_cast<SVGFilterPrimit iveStandardAttributes*>(object->node());
365 349
366 for (; it != end; ++it) { 350 for (; it != end; ++it) {
367 FilterData* filterData = it->second; 351 FilterData* filterData = it->second;
368 if (!filterData->isBuilt) 352 if (filterData->state != FilterData::Built)
369 continue; 353 continue;
370 354
371 SVGFilterBuilder* builder = filterData->builder.get(); 355 SVGFilterBuilder* builder = filterData->builder.get();
372 FilterEffect* effect = builder->effectByRenderer(object); 356 FilterEffect* effect = builder->effectByRenderer(object);
373 if (!effect) 357 if (!effect)
374 continue; 358 continue;
375 // Since all effects shares the same attribute value, all 359 // Since all effects shares the same attribute value, all
376 // or none of them will be changed. 360 // or none of them will be changed.
377 if (!primitve->setFilterEffectAttribute(effect, attribute)) 361 if (!primitve->setFilterEffectAttribute(effect, attribute))
378 return; 362 return;
379 builder->clearResultsRecursive(effect); 363 builder->clearResultsRecursive(effect);
380 364
381 // Repaint the image on the screen. 365 // Repaint the image on the screen.
382 markClientForInvalidation(it->first, RepaintInvalidation); 366 markClientForInvalidation(it->first, RepaintInvalidation);
383 } 367 }
384 } 368 }
385 369
386 } 370 }
387 #endif 371 #endif
OLDNEW
« no previous file with comments | « Source/WebCore/rendering/svg/RenderSVGResourceFilter.h ('k') | Source/WebCore/rendering/svg/RenderSVGRoot.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698