Modified: trunk/Source/WebCore/ChangeLog (142371 => 142372)
--- trunk/Source/WebCore/ChangeLog 2013-02-09 19:01:43 UTC (rev 142371)
+++ trunk/Source/WebCore/ChangeLog 2013-02-09 19:05:20 UTC (rev 142372)
@@ -1,3 +1,33 @@
+2013-02-09 Stephen White <[email protected]>
+
+ [skia] Fix memory management in SkiaImageFilterBuilder and friends.
+ https://bugs.webkit.org/show_bug.cgi?id=109326
+
+ Sadly, skia has no official ref-counted pointers, so we must make do
+ with SkAutoTUnref.
+
+ Reviewed by James Robinson.
+
+ Correctness covered by existing tests in css3/filters.
+
+ * platform/graphics/filters/skia/FEBlendSkia.cpp:
+ (WebCore::FEBlend::createImageFilter):
+ * platform/graphics/filters/skia/FEComponentTransferSkia.cpp:
+ (WebCore::FEComponentTransfer::createImageFilter):
+ * platform/graphics/filters/skia/FELightingSkia.cpp:
+ (WebCore::FELighting::createImageFilter):
+ Adopt refs produced by the build() pass with SkAutoTUnref.
+ * platform/graphics/filters/skia/SkiaImageFilterBuilder.cpp:
+ (WebCore::SkiaImageFilterBuilder::~SkiaImageFilterBuilder):
+ Unref the builder's hashmap effect pointers.
+ (WebCore::SkiaImageFilterBuilder::build):
+ Ref the pointer returned to the caller, and use SkAutoTUnref
+ internally while building the tree.
+ * platform/graphics/filters/skia/SkiaImageFilterBuilder.h:
+ (SkiaImageFilterBuilder):
+ Add a destructor to SkiaImageFilterBuilder.
+
+
2013-02-09 Dominic Mazzoni <[email protected]>
AX: Rename AXObject::cachedIsIgnoredValue to lastKnownIsIgnoredValue
Modified: trunk/Source/WebCore/platform/graphics/filters/skia/FEBlendSkia.cpp (142371 => 142372)
--- trunk/Source/WebCore/platform/graphics/filters/skia/FEBlendSkia.cpp 2013-02-09 19:01:43 UTC (rev 142371)
+++ trunk/Source/WebCore/platform/graphics/filters/skia/FEBlendSkia.cpp 2013-02-09 19:05:20 UTC (rev 142372)
@@ -92,8 +92,8 @@
SkImageFilter* FEBlend::createImageFilter(SkiaImageFilterBuilder* builder)
{
- SkImageFilter* foreground = builder->build(inputEffect(0));
- SkImageFilter* background = ""
+ SkAutoTUnref<SkImageFilter> foreground(builder->build(inputEffect(0)));
+ SkAutoTUnref<SkImageFilter> background(builder->build(inputEffect(1)));
SkBlendImageFilter::Mode mode = toSkiaMode(m_mode);
return new SkBlendImageFilter(mode, background, foreground);
}
Modified: trunk/Source/WebCore/platform/graphics/filters/skia/FEComponentTransferSkia.cpp (142371 => 142372)
--- trunk/Source/WebCore/platform/graphics/filters/skia/FEComponentTransferSkia.cpp 2013-02-09 19:01:43 UTC (rev 142371)
+++ trunk/Source/WebCore/platform/graphics/filters/skia/FEComponentTransferSkia.cpp 2013-02-09 19:05:20 UTC (rev 142372)
@@ -60,7 +60,7 @@
SkImageFilter* FEComponentTransfer::createImageFilter(SkiaImageFilterBuilder* builder)
{
- SkImageFilter* input = builder->build(inputEffect(0));
+ SkAutoTUnref<SkImageFilter> input(builder->build(inputEffect(0)));
unsigned char rValues[256], gValues[256], bValues[256], aValues[256];
getValues(rValues, gValues, bValues, aValues);
Modified: trunk/Source/WebCore/platform/graphics/filters/skia/FELightingSkia.cpp (142371 => 142372)
--- trunk/Source/WebCore/platform/graphics/filters/skia/FELightingSkia.cpp 2013-02-09 19:01:43 UTC (rev 142371)
+++ trunk/Source/WebCore/platform/graphics/filters/skia/FELightingSkia.cpp 2013-02-09 19:05:20 UTC (rev 142372)
@@ -38,7 +38,7 @@
SkImageFilter* FELighting::createImageFilter(SkiaImageFilterBuilder* builder)
{
- SkImageFilter* input = builder ? builder->build(inputEffect(0)) : 0;
+ SkAutoTUnref<SkImageFilter> input(builder ? builder->build(inputEffect(0)) : 0);
switch (m_lightSource->type()) {
case LS_DISTANT: {
DistantLightSource* distantLightSource = static_cast<DistantLightSource*>(m_lightSource.get());
Modified: trunk/Source/WebCore/platform/graphics/filters/skia/SkiaImageFilterBuilder.cpp (142371 => 142372)
--- trunk/Source/WebCore/platform/graphics/filters/skia/SkiaImageFilterBuilder.cpp 2013-02-09 19:01:43 UTC (rev 142371)
+++ trunk/Source/WebCore/platform/graphics/filters/skia/SkiaImageFilterBuilder.cpp 2013-02-09 19:05:20 UTC (rev 142372)
@@ -165,23 +165,31 @@
{
}
+SkiaImageFilterBuilder::~SkiaImageFilterBuilder()
+{
+ for (FilterBuilderHashMap::iterator it = m_map.begin(); it != m_map.end(); ++it)
+ SkSafeUnref(it->value);
+}
+
SkImageFilter* SkiaImageFilterBuilder::build(FilterEffect* effect)
{
if (!effect)
return 0;
+ SkImageFilter* filter = 0;
FilterBuilderHashMap::iterator it = m_map.find(effect);
if (it != m_map.end())
- return it->value;
-
- SkImageFilter* filter = effect->createImageFilter(this);
- m_map.set(effect, filter);
+ filter = it->value;
+ else if ((filter = effect->createImageFilter(this)))
+ m_map.set(effect, filter);
+ // The hash map has a ref, so we return a new ref for the caller.
+ SkSafeRef(filter);
return filter;
}
SkImageFilter* SkiaImageFilterBuilder::build(const FilterOperations& operations)
{
- SkImageFilter* filter = 0;
+ SkAutoTUnref<SkImageFilter> filter;
SkScalar matrix[20];
for (size_t i = 0; i < operations.size(); ++i) {
const FilterOperation& op = *operations.at(i);
@@ -189,65 +197,65 @@
case FilterOperation::REFERENCE: {
FilterEffect* filterEffect = static_cast<const ReferenceFilterOperation*>(&op)->filterEffect();
// FIXME: hook up parent filter to image source
- filter = SkiaImageFilterBuilder::build(filterEffect);
+ filter.reset(SkiaImageFilterBuilder::build(filterEffect));
break;
}
case FilterOperation::GRAYSCALE: {
float amount = static_cast<const BasicColorMatrixFilterOperation*>(&op)->amount();
getGrayscaleMatrix(1 - amount, matrix);
- filter = createMatrixImageFilter(matrix, filter);
+ filter.reset(createMatrixImageFilter(matrix, filter));
break;
}
case FilterOperation::SEPIA: {
float amount = static_cast<const BasicColorMatrixFilterOperation*>(&op)->amount();
getSepiaMatrix(1 - amount, matrix);
- filter = createMatrixImageFilter(matrix, filter);
+ filter.reset(createMatrixImageFilter(matrix, filter));
break;
}
case FilterOperation::SATURATE: {
float amount = static_cast<const BasicColorMatrixFilterOperation*>(&op)->amount();
getSaturateMatrix(amount, matrix);
- filter = createMatrixImageFilter(matrix, filter);
+ filter.reset(createMatrixImageFilter(matrix, filter));
break;
}
case FilterOperation::HUE_ROTATE: {
float amount = static_cast<const BasicColorMatrixFilterOperation*>(&op)->amount();
getHueRotateMatrix(amount, matrix);
- filter = createMatrixImageFilter(matrix, filter);
+ filter.reset(createMatrixImageFilter(matrix, filter));
break;
}
case FilterOperation::INVERT: {
float amount = static_cast<const BasicComponentTransferFilterOperation*>(&op)->amount();
getInvertMatrix(amount, matrix);
- filter = createMatrixImageFilter(matrix, filter);
+ filter.reset(createMatrixImageFilter(matrix, filter));
break;
}
case FilterOperation::OPACITY: {
float amount = static_cast<const BasicComponentTransferFilterOperation*>(&op)->amount();
getOpacityMatrix(amount, matrix);
- filter = createMatrixImageFilter(matrix, filter);
+ filter.reset(createMatrixImageFilter(matrix, filter));
break;
}
case FilterOperation::BRIGHTNESS: {
float amount = static_cast<const BasicComponentTransferFilterOperation*>(&op)->amount();
getBrightnessMatrix(amount, matrix);
- filter = createMatrixImageFilter(matrix, filter);
+ filter.reset(createMatrixImageFilter(matrix, filter));
break;
}
case FilterOperation::CONTRAST: {
float amount = static_cast<const BasicComponentTransferFilterOperation*>(&op)->amount();
getContrastMatrix(amount, matrix);
- filter = createMatrixImageFilter(matrix, filter);
+ filter.reset(createMatrixImageFilter(matrix, filter));
break;
}
case FilterOperation::BLUR: {
float pixelRadius = static_cast<const BlurFilterOperation*>(&op)->stdDeviation().getFloatValue();
- filter = new SkBlurImageFilter(pixelRadius, pixelRadius, filter);
+ filter.reset(new SkBlurImageFilter(pixelRadius, pixelRadius, filter));
break;
}
case FilterOperation::DROP_SHADOW: {
const DropShadowFilterOperation* drop = static_cast<const DropShadowFilterOperation*>(&op);
- filter = new DropShadowImageFilter(SkIntToScalar(drop->x()), SkIntToScalar(drop->y()), SkIntToScalar(drop->stdDeviation()), drop->color().rgb(), filter);
+ filter.reset(new DropShadowImageFilter(SkIntToScalar(drop->x()), SkIntToScalar(drop->y()), SkIntToScalar(drop->stdDeviation()), drop->color().rgb(), filter));
break;
}
#if ENABLE(CSS_SHADERS)
@@ -260,7 +268,7 @@
break;
}
}
- return filter;
+ return filter.detach();
}
};
Modified: trunk/Source/WebCore/platform/graphics/filters/skia/SkiaImageFilterBuilder.h (142371 => 142372)
--- trunk/Source/WebCore/platform/graphics/filters/skia/SkiaImageFilterBuilder.h 2013-02-09 19:01:43 UTC (rev 142371)
+++ trunk/Source/WebCore/platform/graphics/filters/skia/SkiaImageFilterBuilder.h 2013-02-09 19:05:20 UTC (rev 142372)
@@ -37,6 +37,7 @@
class SkiaImageFilterBuilder {
public:
SkiaImageFilterBuilder();
+ ~SkiaImageFilterBuilder();
SkImageFilter* build(FilterEffect*);
SkImageFilter* build(const FilterOperations&);