|
1 /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*- |
|
2 * This Source Code Form is subject to the terms of the Mozilla Public |
|
3 * License, v. 2.0. If a copy of the MPL was not distributed with this |
|
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
5 |
|
6 #include "FilterProcessing.h" |
|
7 |
|
8 namespace mozilla { |
|
9 namespace gfx { |
|
10 |
|
11 TemporaryRef<DataSourceSurface> |
|
12 FilterProcessing::ExtractAlpha(DataSourceSurface* aSource) |
|
13 { |
|
14 IntSize size = aSource->GetSize(); |
|
15 RefPtr<DataSourceSurface> alpha = Factory::CreateDataSourceSurface(size, SurfaceFormat::A8); |
|
16 uint8_t* sourceData = aSource->GetData(); |
|
17 int32_t sourceStride = aSource->Stride(); |
|
18 uint8_t* alphaData = alpha->GetData(); |
|
19 int32_t alphaStride = alpha->Stride(); |
|
20 |
|
21 if (Factory::HasSSE2()) { |
|
22 #ifdef USE_SSE2 |
|
23 ExtractAlpha_SSE2(size, sourceData, sourceStride, alphaData, alphaStride); |
|
24 #endif |
|
25 } else { |
|
26 ExtractAlpha_Scalar(size, sourceData, sourceStride, alphaData, alphaStride); |
|
27 } |
|
28 |
|
29 return alpha; |
|
30 } |
|
31 |
|
32 TemporaryRef<DataSourceSurface> |
|
33 FilterProcessing::ConvertToB8G8R8A8(SourceSurface* aSurface) |
|
34 { |
|
35 if (Factory::HasSSE2()) { |
|
36 #ifdef USE_SSE2 |
|
37 return ConvertToB8G8R8A8_SSE2(aSurface); |
|
38 #endif |
|
39 } |
|
40 return ConvertToB8G8R8A8_Scalar(aSurface); |
|
41 } |
|
42 |
|
43 TemporaryRef<DataSourceSurface> |
|
44 FilterProcessing::ApplyBlending(DataSourceSurface* aInput1, DataSourceSurface* aInput2, |
|
45 BlendMode aBlendMode) |
|
46 { |
|
47 if (Factory::HasSSE2()) { |
|
48 #ifdef USE_SSE2 |
|
49 return ApplyBlending_SSE2(aInput1, aInput2, aBlendMode); |
|
50 #endif |
|
51 } |
|
52 return ApplyBlending_Scalar(aInput1, aInput2, aBlendMode); |
|
53 } |
|
54 |
|
55 void |
|
56 FilterProcessing::ApplyMorphologyHorizontal(uint8_t* aSourceData, int32_t aSourceStride, |
|
57 uint8_t* aDestData, int32_t aDestStride, |
|
58 const IntRect& aDestRect, int32_t aRadius, |
|
59 MorphologyOperator aOp) |
|
60 { |
|
61 if (Factory::HasSSE2()) { |
|
62 #ifdef USE_SSE2 |
|
63 ApplyMorphologyHorizontal_SSE2( |
|
64 aSourceData, aSourceStride, aDestData, aDestStride, aDestRect, aRadius, aOp); |
|
65 #endif |
|
66 } else { |
|
67 ApplyMorphologyHorizontal_Scalar( |
|
68 aSourceData, aSourceStride, aDestData, aDestStride, aDestRect, aRadius, aOp); |
|
69 } |
|
70 } |
|
71 |
|
72 void |
|
73 FilterProcessing::ApplyMorphologyVertical(uint8_t* aSourceData, int32_t aSourceStride, |
|
74 uint8_t* aDestData, int32_t aDestStride, |
|
75 const IntRect& aDestRect, int32_t aRadius, |
|
76 MorphologyOperator aOp) |
|
77 { |
|
78 if (Factory::HasSSE2()) { |
|
79 #ifdef USE_SSE2 |
|
80 ApplyMorphologyVertical_SSE2( |
|
81 aSourceData, aSourceStride, aDestData, aDestStride, aDestRect, aRadius, aOp); |
|
82 #endif |
|
83 } else { |
|
84 ApplyMorphologyVertical_Scalar( |
|
85 aSourceData, aSourceStride, aDestData, aDestStride, aDestRect, aRadius, aOp); |
|
86 } |
|
87 } |
|
88 |
|
89 TemporaryRef<DataSourceSurface> |
|
90 FilterProcessing::ApplyColorMatrix(DataSourceSurface* aInput, const Matrix5x4 &aMatrix) |
|
91 { |
|
92 if (Factory::HasSSE2()) { |
|
93 #ifdef USE_SSE2 |
|
94 return ApplyColorMatrix_SSE2(aInput, aMatrix); |
|
95 #endif |
|
96 } |
|
97 return ApplyColorMatrix_Scalar(aInput, aMatrix); |
|
98 } |
|
99 |
|
100 void |
|
101 FilterProcessing::ApplyComposition(DataSourceSurface* aSource, DataSourceSurface* aDest, |
|
102 CompositeOperator aOperator) |
|
103 { |
|
104 if (Factory::HasSSE2()) { |
|
105 #ifdef USE_SSE2 |
|
106 ApplyComposition_SSE2(aSource, aDest, aOperator); |
|
107 #endif |
|
108 } else { |
|
109 ApplyComposition_Scalar(aSource, aDest, aOperator); |
|
110 } |
|
111 } |
|
112 |
|
113 void |
|
114 FilterProcessing::SeparateColorChannels(DataSourceSurface* aSource, |
|
115 RefPtr<DataSourceSurface>& aChannel0, |
|
116 RefPtr<DataSourceSurface>& aChannel1, |
|
117 RefPtr<DataSourceSurface>& aChannel2, |
|
118 RefPtr<DataSourceSurface>& aChannel3) |
|
119 { |
|
120 IntSize size = aSource->GetSize(); |
|
121 aChannel0 = Factory::CreateDataSourceSurface(size, SurfaceFormat::A8); |
|
122 aChannel1 = Factory::CreateDataSourceSurface(size, SurfaceFormat::A8); |
|
123 aChannel2 = Factory::CreateDataSourceSurface(size, SurfaceFormat::A8); |
|
124 aChannel3 = Factory::CreateDataSourceSurface(size, SurfaceFormat::A8); |
|
125 uint8_t* sourceData = aSource->GetData(); |
|
126 int32_t sourceStride = aSource->Stride(); |
|
127 uint8_t* channel0Data = aChannel0->GetData(); |
|
128 uint8_t* channel1Data = aChannel1->GetData(); |
|
129 uint8_t* channel2Data = aChannel2->GetData(); |
|
130 uint8_t* channel3Data = aChannel3->GetData(); |
|
131 int32_t channelStride = aChannel0->Stride(); |
|
132 |
|
133 if (Factory::HasSSE2()) { |
|
134 #ifdef USE_SSE2 |
|
135 SeparateColorChannels_SSE2(size, sourceData, sourceStride, channel0Data, channel1Data, channel2Data, channel3Data, channelStride); |
|
136 #endif |
|
137 } else { |
|
138 SeparateColorChannels_Scalar(size, sourceData, sourceStride, channel0Data, channel1Data, channel2Data, channel3Data, channelStride); |
|
139 } |
|
140 } |
|
141 |
|
142 TemporaryRef<DataSourceSurface> |
|
143 FilterProcessing::CombineColorChannels(DataSourceSurface* aChannel0, DataSourceSurface* aChannel1, |
|
144 DataSourceSurface* aChannel2, DataSourceSurface* aChannel3) |
|
145 { |
|
146 IntSize size = aChannel0->GetSize(); |
|
147 RefPtr<DataSourceSurface> result = |
|
148 Factory::CreateDataSourceSurface(size, SurfaceFormat::B8G8R8A8); |
|
149 int32_t resultStride = result->Stride(); |
|
150 uint8_t* resultData = result->GetData(); |
|
151 int32_t channelStride = aChannel0->Stride(); |
|
152 uint8_t* channel0Data = aChannel0->GetData(); |
|
153 uint8_t* channel1Data = aChannel1->GetData(); |
|
154 uint8_t* channel2Data = aChannel2->GetData(); |
|
155 uint8_t* channel3Data = aChannel3->GetData(); |
|
156 |
|
157 if (Factory::HasSSE2()) { |
|
158 #ifdef USE_SSE2 |
|
159 CombineColorChannels_SSE2(size, resultStride, resultData, channelStride, channel0Data, channel1Data, channel2Data, channel3Data); |
|
160 #endif |
|
161 } else { |
|
162 CombineColorChannels_Scalar(size, resultStride, resultData, channelStride, channel0Data, channel1Data, channel2Data, channel3Data); |
|
163 } |
|
164 |
|
165 return result; |
|
166 } |
|
167 |
|
168 void |
|
169 FilterProcessing::DoPremultiplicationCalculation(const IntSize& aSize, |
|
170 uint8_t* aTargetData, int32_t aTargetStride, |
|
171 uint8_t* aSourceData, int32_t aSourceStride) |
|
172 { |
|
173 if (Factory::HasSSE2()) { |
|
174 #ifdef USE_SSE2 |
|
175 DoPremultiplicationCalculation_SSE2( |
|
176 aSize, aTargetData, aTargetStride, aSourceData, aSourceStride); |
|
177 #endif |
|
178 } else { |
|
179 DoPremultiplicationCalculation_Scalar( |
|
180 aSize, aTargetData, aTargetStride, aSourceData, aSourceStride); |
|
181 } |
|
182 } |
|
183 |
|
184 void |
|
185 FilterProcessing::DoUnpremultiplicationCalculation(const IntSize& aSize, |
|
186 uint8_t* aTargetData, int32_t aTargetStride, |
|
187 uint8_t* aSourceData, int32_t aSourceStride) |
|
188 { |
|
189 if (Factory::HasSSE2()) { |
|
190 #ifdef USE_SSE2 |
|
191 DoUnpremultiplicationCalculation_SSE2( |
|
192 aSize, aTargetData, aTargetStride, aSourceData, aSourceStride); |
|
193 #endif |
|
194 } else { |
|
195 DoUnpremultiplicationCalculation_Scalar( |
|
196 aSize, aTargetData, aTargetStride, aSourceData, aSourceStride); |
|
197 } |
|
198 } |
|
199 |
|
200 TemporaryRef<DataSourceSurface> |
|
201 FilterProcessing::RenderTurbulence(const IntSize &aSize, const Point &aOffset, const Size &aBaseFrequency, |
|
202 int32_t aSeed, int aNumOctaves, TurbulenceType aType, bool aStitch, const Rect &aTileRect) |
|
203 { |
|
204 if (Factory::HasSSE2()) { |
|
205 #ifdef USE_SSE2 |
|
206 return RenderTurbulence_SSE2(aSize, aOffset, aBaseFrequency, aSeed, aNumOctaves, aType, aStitch, aTileRect); |
|
207 #endif |
|
208 } |
|
209 return RenderTurbulence_Scalar(aSize, aOffset, aBaseFrequency, aSeed, aNumOctaves, aType, aStitch, aTileRect); |
|
210 } |
|
211 |
|
212 TemporaryRef<DataSourceSurface> |
|
213 FilterProcessing::ApplyArithmeticCombine(DataSourceSurface* aInput1, DataSourceSurface* aInput2, Float aK1, Float aK2, Float aK3, Float aK4) |
|
214 { |
|
215 if (Factory::HasSSE2()) { |
|
216 #ifdef USE_SSE2 |
|
217 return ApplyArithmeticCombine_SSE2(aInput1, aInput2, aK1, aK2, aK3, aK4); |
|
218 #endif |
|
219 } |
|
220 return ApplyArithmeticCombine_Scalar(aInput1, aInput2, aK1, aK2, aK3, aK4); |
|
221 } |
|
222 |
|
223 } // namespace gfx |
|
224 } // namespace mozilla |