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

Side by Side Diff: third_party/WebKit/Source/core/paint/FilterEffectBuilder.cpp

Issue 2349183002: Turn FilterEffectBuilder into a stack-allocated helper (Closed)
Patch Set: Created 4 years, 3 months 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) 2011 Apple Inc. All rights reserved. 2 * Copyright (C) 2011 Apple Inc. All rights reserved.
3 * Copyright (C) 2013 Google Inc. All rights reserved. 3 * Copyright (C) 2013 Google Inc. All rights reserved.
4 * 4 *
5 * Redistribution and use in source and binary forms, with or without 5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions 6 * modification, are permitted provided that the following conditions
7 * are met: 7 * are met:
8 * 1. Redistributions of source code must retain the above copyright 8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer. 9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright 10 * 2. Redistributions in binary form must reproduce the above copyright
(...skipping 20 matching lines...) Expand all
31 #include "core/svg/SVGLengthContext.h" 31 #include "core/svg/SVGLengthContext.h"
32 #include "core/svg/graphics/filters/SVGFilterBuilder.h" 32 #include "core/svg/graphics/filters/SVGFilterBuilder.h"
33 #include "platform/LengthFunctions.h" 33 #include "platform/LengthFunctions.h"
34 #include "platform/graphics/ColorSpace.h" 34 #include "platform/graphics/ColorSpace.h"
35 #include "platform/graphics/filters/FEBoxReflect.h" 35 #include "platform/graphics/filters/FEBoxReflect.h"
36 #include "platform/graphics/filters/FEColorMatrix.h" 36 #include "platform/graphics/filters/FEColorMatrix.h"
37 #include "platform/graphics/filters/FEComponentTransfer.h" 37 #include "platform/graphics/filters/FEComponentTransfer.h"
38 #include "platform/graphics/filters/FEDropShadow.h" 38 #include "platform/graphics/filters/FEDropShadow.h"
39 #include "platform/graphics/filters/FEGaussianBlur.h" 39 #include "platform/graphics/filters/FEGaussianBlur.h"
40 #include "platform/graphics/filters/Filter.h" 40 #include "platform/graphics/filters/Filter.h"
41 #include "platform/graphics/filters/FilterEffect.h"
41 #include "platform/graphics/filters/FilterOperations.h" 42 #include "platform/graphics/filters/FilterOperations.h"
42 #include "platform/graphics/filters/SourceGraphic.h" 43 #include "platform/graphics/filters/SourceGraphic.h"
43 #include "wtf/MathExtras.h" 44 #include "wtf/MathExtras.h"
44 #include <algorithm> 45 #include <algorithm>
45 46
46 namespace blink { 47 namespace blink {
47 48
48 namespace { 49 namespace {
49 50
50 inline void endMatrixRow(Vector<float>& matrix) 51 inline void endMatrixRow(Vector<float>& matrix)
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
113 matrix.uncheckedAppend(clampTo<float>(0.534 - 0.534 * oneMinusAmount)); 114 matrix.uncheckedAppend(clampTo<float>(0.534 - 0.534 * oneMinusAmount));
114 matrix.uncheckedAppend(clampTo<float>(0.131 + 0.869 * oneMinusAmount)); 115 matrix.uncheckedAppend(clampTo<float>(0.131 + 0.869 * oneMinusAmount));
115 endMatrixRow(matrix); 116 endMatrixRow(matrix);
116 117
117 lastMatrixRow(matrix); 118 lastMatrixRow(matrix);
118 return matrix; 119 return matrix;
119 } 120 }
120 121
121 } // namespace 122 } // namespace
122 123
123 FilterEffectBuilder::FilterEffectBuilder() 124 FilterEffectBuilder::FilterEffectBuilder(
125 Element* target,
126 const FloatRect& zoomedReferenceBox, float zoom,
127 const SkPaint* fillPaint, const SkPaint* strokePaint)
128 : m_targetContext(target)
129 , m_referenceBox(zoomedReferenceBox)
130 , m_zoom(zoom)
131 , m_fillPaint(fillPaint)
132 , m_strokePaint(strokePaint)
124 { 133 {
134 if (m_zoom != 1)
135 m_referenceBox.scale(1 / m_zoom);
125 } 136 }
126 137
127 FilterEffectBuilder::~FilterEffectBuilder() 138 FilterEffect* FilterEffectBuilder::buildFilterEffect(const FilterOperations& ope rations) const
128 {
129 }
130
131 DEFINE_TRACE(FilterEffectBuilder)
132 {
133 visitor->trace(m_lastEffect);
134 }
135
136 bool FilterEffectBuilder::build(Element* element, const FilterOperations& operat ions, float zoom, const FloatRect& zoomedReferenceBox, const SkPaint* fillPaint, const SkPaint* strokePaint)
137 { 139 {
138 // Create a parent filter for shorthand filters. These have already been sca led by the CSS code for page zoom, so scale is 1.0 here. 140 // Create a parent filter for shorthand filters. These have already been sca led by the CSS code for page zoom, so scale is 1.0 here.
139 Filter* parentFilter = Filter::create(1.0f); 141 Filter* parentFilter = Filter::create(1.0f);
140 FilterEffect* previousEffect = parentFilter->getSourceGraphic(); 142 FilterEffect* previousEffect = parentFilter->getSourceGraphic();
141 for (size_t i = 0; i < operations.operations().size(); ++i) { 143 for (size_t i = 0; i < operations.operations().size(); ++i) {
142 FilterEffect* effect = nullptr; 144 FilterEffect* effect = nullptr;
143 FilterOperation* filterOperation = operations.operations().at(i).get(); 145 FilterOperation* filterOperation = operations.operations().at(i).get();
144 switch (filterOperation->type()) { 146 switch (filterOperation->type()) {
145 case FilterOperation::REFERENCE: { 147 case FilterOperation::REFERENCE: {
146 Filter* referenceFilter = buildReferenceFilter(toReferenceFilterOper ation(*filterOperation), zoomedReferenceBox, fillPaint, strokePaint, *element, p reviousEffect, zoom); 148 Filter* referenceFilter = buildReferenceFilter(toReferenceFilterOper ation(*filterOperation), previousEffect);
147 if (referenceFilter) 149 if (referenceFilter)
148 effect = referenceFilter->lastEffect(); 150 effect = referenceFilter->lastEffect();
149 break; 151 break;
150 } 152 }
151 case FilterOperation::GRAYSCALE: { 153 case FilterOperation::GRAYSCALE: {
152 Vector<float> inputParameters = grayscaleMatrix(toBasicColorMatrixFi lterOperation(filterOperation)->amount()); 154 Vector<float> inputParameters = grayscaleMatrix(toBasicColorMatrixFi lterOperation(filterOperation)->amount());
153 effect = FEColorMatrix::create(parentFilter, FECOLORMATRIX_TYPE_MATR IX, inputParameters); 155 effect = FEColorMatrix::create(parentFilter, FECOLORMATRIX_TYPE_MATR IX, inputParameters);
154 break; 156 break;
155 } 157 }
156 case FilterOperation::SEPIA: { 158 case FilterOperation::SEPIA: {
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
243 // Unlike SVG, filters applied here should not clip to their pri mitive subregions. 245 // Unlike SVG, filters applied here should not clip to their pri mitive subregions.
244 effect->setClipsToBounds(false); 246 effect->setClipsToBounds(false);
245 effect->setOperatingColorSpace(ColorSpaceDeviceRGB); 247 effect->setOperatingColorSpace(ColorSpaceDeviceRGB);
246 effect->inputEffects().append(previousEffect); 248 effect->inputEffects().append(previousEffect);
247 } 249 }
248 if (previousEffect->originTainted()) 250 if (previousEffect->originTainted())
249 effect->setOriginTainted(); 251 effect->setOriginTainted();
250 previousEffect = effect; 252 previousEffect = effect;
251 } 253 }
252 } 254 }
253 255 return previousEffect;
254 // We need to keep the old effects alive until this point, so that SVG refer ence filters
255 // can share cached resources across frames.
256 m_lastEffect = previousEffect;
257
258 // If we didn't make any effects, tell our caller we are not valid
259 if (!m_lastEffect.get())
260 return false;
261
262 return true;
263 } 256 }
264 257
265 Filter* FilterEffectBuilder::buildReferenceFilter( 258 Filter* FilterEffectBuilder::buildReferenceFilter(
Stephen White 2016/09/19 14:59:36 I wonder if we should now just have two constructo
fs 2016/09/20 08:17:28 My plan is one constructor and one buildReferenceF
266 const ReferenceFilterOperation& referenceOperation, 259 const ReferenceFilterOperation& referenceOperation,
267 const FloatRect& zoomedReferenceBox, 260 FilterEffect* previousEffect) const
268 const SkPaint* fillPaint,
269 const SkPaint* strokePaint,
270 Element& element,
271 FilterEffect* previousEffect,
272 float zoom)
273 { 261 {
274 SVGFilterElement* filterElement = ReferenceFilterBuilder::resolveFilterRefer ence(referenceOperation, element); 262 DCHECK(m_targetContext);
263 SVGFilterElement* filterElement = ReferenceFilterBuilder::resolveFilterRefer ence(referenceOperation, *m_targetContext);
275 if (!filterElement) 264 if (!filterElement)
276 return nullptr; 265 return nullptr;
277 FloatRect referenceBox = zoomedReferenceBox; 266 return buildReferenceFilter(*filterElement, previousEffect);
278 referenceBox.scale(1.0f / zoom);
279 return buildReferenceFilter(*filterElement, referenceBox, fillPaint, strokeP aint, previousEffect, zoom);
280 } 267 }
281 268
282 Filter* FilterEffectBuilder::buildReferenceFilter( 269 Filter* FilterEffectBuilder::buildReferenceFilter(
283 SVGFilterElement& filterElement, 270 SVGFilterElement& filterElement,
284 const FloatRect& referenceBox,
285 const SkPaint* fillPaint,
286 const SkPaint* strokePaint,
287 FilterEffect* previousEffect, 271 FilterEffect* previousEffect,
288 float zoom, 272 SVGFilterGraphNodeMap* nodeMap) const
289 SVGFilterGraphNodeMap* nodeMap)
290 { 273 {
291 FloatRect filterRegion = SVGLengthContext::resolveRectangle<SVGFilterElement >(&filterElement, filterElement.filterUnits()->currentValue()->enumValue(), refe renceBox); 274 FloatRect filterRegion = SVGLengthContext::resolveRectangle<SVGFilterElement >(&filterElement, filterElement.filterUnits()->currentValue()->enumValue(), m_re ferenceBox);
292 // TODO(fs): We rely on the presence of a node map here to opt-in to the 275 // TODO(fs): We rely on the presence of a node map here to opt-in to the
293 // check for an empty filter region. The reason for this is that we lack a 276 // check for an empty filter region. The reason for this is that we lack a
294 // viewport to resolve against for HTML content. This is crbug.com/512453. 277 // viewport to resolve against for HTML content. This is crbug.com/512453.
295 if (nodeMap && filterRegion.isEmpty()) 278 if (nodeMap && filterRegion.isEmpty())
296 return nullptr; 279 return nullptr;
297 280
298 bool primitiveBoundingBoxMode = filterElement.primitiveUnits()->currentValue ()->enumValue() == SVGUnitTypes::kSvgUnitTypeObjectboundingbox; 281 bool primitiveBoundingBoxMode = filterElement.primitiveUnits()->currentValue ()->enumValue() == SVGUnitTypes::kSvgUnitTypeObjectboundingbox;
299 Filter::UnitScaling unitScaling = primitiveBoundingBoxMode ? Filter::Boundin gBox : Filter::UserSpace; 282 Filter::UnitScaling unitScaling = primitiveBoundingBoxMode ? Filter::Boundin gBox : Filter::UserSpace;
300 Filter* result = Filter::create(referenceBox, filterRegion, zoom, unitScalin g); 283 Filter* result = Filter::create(m_referenceBox, filterRegion, m_zoom, unitSc aling);
301 if (!previousEffect) 284 if (!previousEffect)
302 previousEffect = result->getSourceGraphic(); 285 previousEffect = result->getSourceGraphic();
303 SVGFilterBuilder builder(previousEffect, nodeMap, fillPaint, strokePaint); 286 SVGFilterBuilder builder(previousEffect, nodeMap, m_fillPaint, m_strokePaint );
304 builder.buildGraph(result, filterElement, referenceBox); 287 builder.buildGraph(result, filterElement, m_referenceBox);
305 result->setLastEffect(builder.lastEffect()); 288 result->setLastEffect(builder.lastEffect());
306 return result; 289 return result;
307 } 290 }
308 291
309 } // namespace blink 292 } // namespace blink
310 293
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/core/paint/FilterEffectBuilder.h ('k') | third_party/WebKit/Source/core/paint/PaintLayer.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698