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 |