| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2012 Google Inc. All rights reserved. | 2 * Copyright (C) 2012 Google Inc. All rights reserved. |
| 3 * | 3 * |
| 4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
| 5 * modification, are permitted provided that the following conditions | 5 * modification, are permitted provided that the following conditions |
| 6 * are met: | 6 * are met: |
| 7 * | 7 * |
| 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 11 matching lines...) Expand all Loading... |
| 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
| 23 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 23 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 24 */ | 24 */ |
| 25 | 25 |
| 26 #include "platform/graphics/filters/SkiaImageFilterBuilder.h" | 26 #include "platform/graphics/filters/SkiaImageFilterBuilder.h" |
| 27 | 27 |
| 28 #include "SkBlurImageFilter.h" | 28 #include "SkBlurImageFilter.h" |
| 29 #include "SkColorFilterImageFilter.h" | 29 #include "SkColorFilterImageFilter.h" |
| 30 #include "SkColorMatrixFilter.h" | 30 #include "SkColorMatrixFilter.h" |
| 31 #include "SkTableColorFilter.h" | 31 #include "SkTableColorFilter.h" |
| 32 #include "platform/geometry/IntPoint.h" | |
| 33 #include "platform/graphics/BoxReflection.h" | 32 #include "platform/graphics/BoxReflection.h" |
| 34 #include "platform/graphics/CompositorFilterOperations.h" | |
| 35 #include "platform/graphics/filters/FilterEffect.h" | 33 #include "platform/graphics/filters/FilterEffect.h" |
| 36 #include "platform/graphics/filters/FilterOperations.h" | |
| 37 #include "platform/graphics/filters/SourceGraphic.h" | |
| 38 #include "platform/graphics/skia/SkiaUtils.h" | 34 #include "platform/graphics/skia/SkiaUtils.h" |
| 39 #include "third_party/skia/include/core/SkPicture.h" | 35 #include "third_party/skia/include/core/SkPicture.h" |
| 40 #include "third_party/skia/include/core/SkXfermode.h" | 36 #include "third_party/skia/include/core/SkXfermode.h" |
| 41 #include "third_party/skia/include/effects/SkPictureImageFilter.h" | 37 #include "third_party/skia/include/effects/SkPictureImageFilter.h" |
| 42 #include "third_party/skia/include/effects/SkXfermodeImageFilter.h" | 38 #include "third_party/skia/include/effects/SkXfermodeImageFilter.h" |
| 43 | 39 |
| 44 namespace blink { | 40 namespace blink { |
| 45 namespace SkiaImageFilterBuilder { | 41 namespace SkiaImageFilterBuilder { |
| 46 | 42 |
| 47 namespace { | |
| 48 | |
| 49 void populateSourceGraphicImageFilters(FilterEffect* sourceGraphic, sk_sp<SkImag
eFilter> input, ColorSpace inputColorSpace) | 43 void populateSourceGraphicImageFilters(FilterEffect* sourceGraphic, sk_sp<SkImag
eFilter> input, ColorSpace inputColorSpace) |
| 50 { | 44 { |
| 51 // Prepopulate SourceGraphic with two image filters: one with a null image | 45 // Prepopulate SourceGraphic with two image filters: one with a null image |
| 52 // filter, and the other with a colorspace conversion filter. | 46 // filter, and the other with a colorspace conversion filter. |
| 53 // We don't know what color space the interior nodes will request, so we | 47 // We don't know what color space the interior nodes will request, so we |
| 54 // have to initialize SourceGraphic with both options. | 48 // have to initialize SourceGraphic with both options. |
| 55 // Since we know SourceGraphic is always PM-valid, we also use these for | 49 // Since we know SourceGraphic is always PM-valid, we also use these for |
| 56 // the PM-validated options. | 50 // the PM-validated options. |
| 57 sk_sp<SkImageFilter> deviceFilter = transformColorSpace(input, inputColorSpa
ce, ColorSpaceDeviceRGB); | 51 sk_sp<SkImageFilter> deviceFilter = transformColorSpace(input, inputColorSpa
ce, ColorSpaceDeviceRGB); |
| 58 sk_sp<SkImageFilter> linearFilter = transformColorSpace(input, inputColorSpa
ce, ColorSpaceLinearRGB); | 52 sk_sp<SkImageFilter> linearFilter = transformColorSpace(input, inputColorSpa
ce, ColorSpaceLinearRGB); |
| 59 sourceGraphic->setImageFilter(ColorSpaceDeviceRGB, false, deviceFilter); | 53 sourceGraphic->setImageFilter(ColorSpaceDeviceRGB, false, deviceFilter); |
| 60 sourceGraphic->setImageFilter(ColorSpaceLinearRGB, false, linearFilter); | 54 sourceGraphic->setImageFilter(ColorSpaceLinearRGB, false, linearFilter); |
| 61 sourceGraphic->setImageFilter(ColorSpaceDeviceRGB, true, deviceFilter); | 55 sourceGraphic->setImageFilter(ColorSpaceDeviceRGB, true, deviceFilter); |
| 62 sourceGraphic->setImageFilter(ColorSpaceLinearRGB, true, linearFilter); | 56 sourceGraphic->setImageFilter(ColorSpaceLinearRGB, true, linearFilter); |
| 63 } | 57 } |
| 64 | 58 |
| 65 } // namespace | |
| 66 | |
| 67 sk_sp<SkImageFilter> build(FilterEffect* effect, ColorSpace colorSpace, bool des
tinationRequiresValidPreMultipliedPixels) | 59 sk_sp<SkImageFilter> build(FilterEffect* effect, ColorSpace colorSpace, bool des
tinationRequiresValidPreMultipliedPixels) |
| 68 { | 60 { |
| 69 if (!effect) | 61 if (!effect) |
| 70 return nullptr; | 62 return nullptr; |
| 71 | 63 |
| 72 bool requiresPMColorValidation = effect->mayProduceInvalidPreMultipliedPixel
s() && destinationRequiresValidPreMultipliedPixels; | 64 bool requiresPMColorValidation = effect->mayProduceInvalidPreMultipliedPixel
s() && destinationRequiresValidPreMultipliedPixels; |
| 73 | 65 |
| 74 if (SkImageFilter* filter = effect->getImageFilter(colorSpace, requiresPMCol
orValidation)) | 66 if (SkImageFilter* filter = effect->getImageFilter(colorSpace, requiresPMCol
orValidation)) |
| 75 return sk_ref_sp(filter); | 67 return sk_ref_sp(filter); |
| 76 | 68 |
| (...skipping 16 matching lines...) Expand all Loading... |
| 93 } | 85 } |
| 94 | 86 |
| 95 void buildSourceGraphic(FilterEffect* sourceGraphic, sk_sp<SkPicture> picture) | 87 void buildSourceGraphic(FilterEffect* sourceGraphic, sk_sp<SkPicture> picture) |
| 96 { | 88 { |
| 97 ASSERT(picture); | 89 ASSERT(picture); |
| 98 SkRect cullRect = picture->cullRect(); | 90 SkRect cullRect = picture->cullRect(); |
| 99 sk_sp<SkImageFilter> filter = SkPictureImageFilter::Make(std::move(picture),
cullRect); | 91 sk_sp<SkImageFilter> filter = SkPictureImageFilter::Make(std::move(picture),
cullRect); |
| 100 populateSourceGraphicImageFilters(sourceGraphic, std::move(filter), sourceGr
aphic->operatingColorSpace()); | 92 populateSourceGraphicImageFilters(sourceGraphic, std::move(filter), sourceGr
aphic->operatingColorSpace()); |
| 101 } | 93 } |
| 102 | 94 |
| 103 CompositorFilterOperations buildFilterOperations(const FilterOperations& operati
ons) | |
| 104 { | |
| 105 ColorSpace currentColorSpace = ColorSpaceDeviceRGB; | |
| 106 | |
| 107 CompositorFilterOperations filters; | |
| 108 for (size_t i = 0; i < operations.size(); ++i) { | |
| 109 const FilterOperation& op = *operations.at(i); | |
| 110 switch (op.type()) { | |
| 111 case FilterOperation::REFERENCE: { | |
| 112 Filter* referenceFilter = toReferenceFilterOperation(op).getFilter()
; | |
| 113 if (referenceFilter && referenceFilter->lastEffect()) { | |
| 114 populateSourceGraphicImageFilters(referenceFilter->getSourceGrap
hic(), nullptr, currentColorSpace); | |
| 115 | |
| 116 FilterEffect* filterEffect = referenceFilter->lastEffect(); | |
| 117 currentColorSpace = filterEffect->operatingColorSpace(); | |
| 118 filters.appendReferenceFilter(SkiaImageFilterBuilder::build(filt
erEffect, currentColorSpace)); | |
| 119 } | |
| 120 break; | |
| 121 } | |
| 122 case FilterOperation::GRAYSCALE: | |
| 123 case FilterOperation::SEPIA: | |
| 124 case FilterOperation::SATURATE: | |
| 125 case FilterOperation::HUE_ROTATE: { | |
| 126 float amount = toBasicColorMatrixFilterOperation(op).amount(); | |
| 127 switch (op.type()) { | |
| 128 case FilterOperation::GRAYSCALE: | |
| 129 filters.appendGrayscaleFilter(amount); | |
| 130 break; | |
| 131 case FilterOperation::SEPIA: | |
| 132 filters.appendSepiaFilter(amount); | |
| 133 break; | |
| 134 case FilterOperation::SATURATE: | |
| 135 filters.appendSaturateFilter(amount); | |
| 136 break; | |
| 137 case FilterOperation::HUE_ROTATE: | |
| 138 filters.appendHueRotateFilter(amount); | |
| 139 break; | |
| 140 default: | |
| 141 ASSERT_NOT_REACHED(); | |
| 142 } | |
| 143 break; | |
| 144 } | |
| 145 case FilterOperation::INVERT: | |
| 146 case FilterOperation::OPACITY: | |
| 147 case FilterOperation::BRIGHTNESS: | |
| 148 case FilterOperation::CONTRAST: { | |
| 149 float amount = toBasicComponentTransferFilterOperation(op).amount(); | |
| 150 switch (op.type()) { | |
| 151 case FilterOperation::INVERT: | |
| 152 filters.appendInvertFilter(amount); | |
| 153 break; | |
| 154 case FilterOperation::OPACITY: | |
| 155 filters.appendOpacityFilter(amount); | |
| 156 break; | |
| 157 case FilterOperation::BRIGHTNESS: | |
| 158 filters.appendBrightnessFilter(amount); | |
| 159 break; | |
| 160 case FilterOperation::CONTRAST: | |
| 161 filters.appendContrastFilter(amount); | |
| 162 break; | |
| 163 default: | |
| 164 ASSERT_NOT_REACHED(); | |
| 165 } | |
| 166 break; | |
| 167 } | |
| 168 case FilterOperation::BLUR: { | |
| 169 float pixelRadius = toBlurFilterOperation(op).stdDeviation().getFloa
tValue(); | |
| 170 filters.appendBlurFilter(pixelRadius); | |
| 171 break; | |
| 172 } | |
| 173 case FilterOperation::DROP_SHADOW: { | |
| 174 const DropShadowFilterOperation& drop = toDropShadowFilterOperation(
op); | |
| 175 filters.appendDropShadowFilter(drop.location(), drop.stdDeviation(),
drop.getColor()); | |
| 176 break; | |
| 177 } | |
| 178 case FilterOperation::BOX_REFLECT: { | |
| 179 // TODO(jbroman): Consider explaining box reflect to the compositor, | |
| 180 // instead of calling this a "reference filter". | |
| 181 const auto& reflection = toBoxReflectFilterOperation(op).reflection(
); | |
| 182 filters.appendReferenceFilter(buildBoxReflectFilter(reflection, null
ptr)); | |
| 183 break; | |
| 184 } | |
| 185 case FilterOperation::NONE: | |
| 186 break; | |
| 187 } | |
| 188 } | |
| 189 if (currentColorSpace != ColorSpaceDeviceRGB) { | |
| 190 // Transform to device color space at the end of processing, if required | |
| 191 sk_sp<SkImageFilter> filter = transformColorSpace(nullptr, currentColorS
pace, ColorSpaceDeviceRGB); | |
| 192 filters.appendReferenceFilter(std::move(filter)); | |
| 193 } | |
| 194 return filters; | |
| 195 } | |
| 196 | |
| 197 sk_sp<SkImageFilter> buildBoxReflectFilter(const BoxReflection& reflection, sk_s
p<SkImageFilter> input) | 95 sk_sp<SkImageFilter> buildBoxReflectFilter(const BoxReflection& reflection, sk_s
p<SkImageFilter> input) |
| 198 { | 96 { |
| 199 sk_sp<SkImageFilter> maskedInput; | 97 sk_sp<SkImageFilter> maskedInput; |
| 200 if (SkPicture* maskPicture = reflection.mask()) { | 98 if (SkPicture* maskPicture = reflection.mask()) { |
| 201 // SkXfermodeImageFilter can choose an excessively large size if the | 99 // SkXfermodeImageFilter can choose an excessively large size if the |
| 202 // mask is smaller than the filtered contents (due to overflow). | 100 // mask is smaller than the filtered contents (due to overflow). |
| 203 // http://skbug.com/5210 | 101 // http://skbug.com/5210 |
| 204 SkImageFilter::CropRect cropRect(maskPicture->cullRect()); | 102 SkImageFilter::CropRect cropRect(maskPicture->cullRect()); |
| 205 maskedInput = SkXfermodeImageFilter::Make( | 103 maskedInput = SkXfermodeImageFilter::Make( |
| 206 SkXfermode::Make(SkXfermode::kSrcIn_Mode), | 104 SkXfermode::Make(SkXfermode::kSrcIn_Mode), |
| 207 SkPictureImageFilter::Make(sk_ref_sp(maskPicture)), | 105 SkPictureImageFilter::Make(sk_ref_sp(maskPicture)), |
| 208 input, &cropRect); | 106 input, &cropRect); |
| 209 } else { | 107 } else { |
| 210 maskedInput = input; | 108 maskedInput = input; |
| 211 } | 109 } |
| 212 sk_sp<SkImageFilter> flipImageFilter = SkImageFilter::MakeMatrixFilter( | 110 sk_sp<SkImageFilter> flipImageFilter = SkImageFilter::MakeMatrixFilter( |
| 213 reflection.reflectionMatrix(), kLow_SkFilterQuality, std::move(maskedInp
ut)); | 111 reflection.reflectionMatrix(), kLow_SkFilterQuality, std::move(maskedInp
ut)); |
| 214 return SkXfermodeImageFilter::Make(nullptr, std::move(flipImageFilter), std:
:move(input), nullptr); | 112 return SkXfermodeImageFilter::Make(nullptr, std::move(flipImageFilter), std:
:move(input), nullptr); |
| 215 } | 113 } |
| 216 | 114 |
| 217 } // namespace SkiaImageFilterBuilder | 115 } // namespace SkiaImageFilterBuilder |
| 218 } // namespace blink | 116 } // namespace blink |
| OLD | NEW |