Chromium Code Reviews| Index: Source/core/platform/graphics/filters/SkiaImageFilterBuilder.cpp |
| diff --git a/Source/core/platform/graphics/filters/SkiaImageFilterBuilder.cpp b/Source/core/platform/graphics/filters/SkiaImageFilterBuilder.cpp |
| index 50c3655ff3aefa010989e6bf9d41d0a3a7df4128..3c8d33025c77901012cd5ed8924a0bdc66bb7b87 100644 |
| --- a/Source/core/platform/graphics/filters/SkiaImageFilterBuilder.cpp |
| +++ b/Source/core/platform/graphics/filters/SkiaImageFilterBuilder.cpp |
| @@ -30,6 +30,8 @@ |
| #include "SkColorFilterImageFilter.h" |
| #include "SkColorMatrixFilter.h" |
| #include "SkMatrix.h" |
| +#include "SkTableColorFilter.h" |
| +#include "core/platform/graphics/ImageBuffer.h" |
| #include "core/platform/graphics/filters/DropShadowImageFilter.h" |
| #include "core/platform/graphics/filters/FilterEffect.h" |
| #include "core/platform/graphics/filters/FilterOperations.h" |
| @@ -171,33 +173,56 @@ SkiaImageFilterBuilder::~SkiaImageFilterBuilder() |
| SkSafeUnref(it->value); |
| } |
| -SkImageFilter* SkiaImageFilterBuilder::build(FilterEffect* effect) |
| +SkImageFilter* SkiaImageFilterBuilder::build(FilterEffect* effect, ColorSpace colorSpace) |
| { |
| if (!effect) |
| return 0; |
| SkImageFilter* filter = 0; |
| - FilterBuilderHashMap::iterator it = m_map.find(effect); |
| + FilterColorSpacePair key(effect, colorSpace); |
| + FilterBuilderHashMap::iterator it = m_map.find(key); |
| if (it != m_map.end()) |
| filter = it->value; |
| - else if ((filter = effect->createImageFilter(this))) |
| - m_map.set(effect, filter); |
| + else { |
| + // Note that we may still need the color transform even if the filter is null |
|
Stephen White
2013/05/10 14:56:18
Hmm.. so effect is always going to have two entrie
sugoi1
2013/05/10 15:10:18
This is for SourceGraphic, which comes up as a NUL
|
| + filter = transformColorSpace(effect->createImageFilter(this), effect->operatingColorSpace(), colorSpace); |
| + m_map.set(key, filter); |
| + } |
| // The hash map has a ref, so we return a new ref for the caller. |
| SkSafeRef(filter); |
| return filter; |
| } |
| +SkImageFilter* SkiaImageFilterBuilder::transformColorSpace( |
| + SkImageFilter* input, ColorSpace srcColorSpace, ColorSpace dstColorSpace) { |
| + if ((srcColorSpace == dstColorSpace) |
| + || (srcColorSpace != ColorSpaceLinearRGB && srcColorSpace != ColorSpaceDeviceRGB) |
| + || (dstColorSpace != ColorSpaceLinearRGB && dstColorSpace != ColorSpaceDeviceRGB)) |
| + return input; |
| + |
| + const uint8_t* lut = 0; |
| + if (dstColorSpace == ColorSpaceLinearRGB) |
| + lut = &ImageBuffer::getLinearRgbLUT()[0]; |
| + else if (dstColorSpace == ColorSpaceDeviceRGB) |
| + lut = &ImageBuffer::getDeviceRgbLUT()[0]; |
| + |
| + return lut ? SkColorFilterImageFilter::Create( |
| + SkTableColorFilter::CreateARGB(0, lut, lut, lut), input) : input; |
| +} |
| + |
| SkImageFilter* SkiaImageFilterBuilder::build(const FilterOperations& operations) |
| { |
| SkAutoTUnref<SkImageFilter> filter; |
| SkScalar matrix[20]; |
| + ColorSpace currentColorSpace = ColorSpaceDeviceRGB; |
| for (size_t i = 0; i < operations.size(); ++i) { |
| const FilterOperation& op = *operations.at(i); |
| switch (op.getOperationType()) { |
| case FilterOperation::REFERENCE: { |
| FilterEffect* filterEffect = static_cast<const ReferenceFilterOperation*>(&op)->filterEffect(); |
| // FIXME: hook up parent filter to image source |
| - filter.reset(SkiaImageFilterBuilder::build(filterEffect)); |
| + currentColorSpace = filterEffect->operatingColorSpace(); |
| + filter.reset(SkiaImageFilterBuilder::build(filterEffect, currentColorSpace)); |
| break; |
| } |
| case FilterOperation::GRAYSCALE: { |
| @@ -266,6 +291,10 @@ SkImageFilter* SkiaImageFilterBuilder::build(const FilterOperations& operations) |
| break; |
| } |
| } |
| + if (currentColorSpace != ColorSpaceDeviceRGB) { |
| + // Go back to device color space at the end |
| + filter.reset(transformColorSpace(filter.get(), currentColorSpace, ColorSpaceDeviceRGB)); |
| + } |
| return filter.detach(); |
| } |