Line data Source code
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 : #include "Logging.h"
8 :
9 : namespace mozilla {
10 : namespace gfx {
11 :
12 : already_AddRefed<DataSourceSurface>
13 0 : FilterProcessing::ExtractAlpha(DataSourceSurface* aSource)
14 : {
15 0 : IntSize size = aSource->GetSize();
16 0 : RefPtr<DataSourceSurface> alpha = Factory::CreateDataSourceSurface(size, SurfaceFormat::A8);
17 0 : if (MOZ2D_WARN_IF(!alpha)) {
18 0 : return nullptr;
19 : }
20 :
21 0 : DataSourceSurface::ScopedMap sourceMap(aSource, DataSourceSurface::READ);
22 0 : DataSourceSurface::ScopedMap alphaMap(alpha, DataSourceSurface::WRITE);
23 0 : if (MOZ2D_WARN_IF(!sourceMap.IsMapped() || !alphaMap.IsMapped())) {
24 0 : return nullptr;
25 : }
26 :
27 0 : uint8_t* sourceData = sourceMap.GetData();
28 0 : int32_t sourceStride = sourceMap.GetStride();
29 0 : uint8_t* alphaData = alphaMap.GetData();
30 0 : int32_t alphaStride = alphaMap.GetStride();
31 :
32 0 : if (Factory::HasSSE2()) {
33 : #ifdef USE_SSE2
34 0 : ExtractAlpha_SSE2(size, sourceData, sourceStride, alphaData, alphaStride);
35 : #endif
36 : } else {
37 0 : ExtractAlpha_Scalar(size, sourceData, sourceStride, alphaData, alphaStride);
38 : }
39 :
40 0 : return alpha.forget();
41 : }
42 :
43 : already_AddRefed<DataSourceSurface>
44 0 : FilterProcessing::ConvertToB8G8R8A8(SourceSurface* aSurface)
45 : {
46 0 : if (Factory::HasSSE2()) {
47 : #ifdef USE_SSE2
48 0 : return ConvertToB8G8R8A8_SSE2(aSurface);
49 : #endif
50 : }
51 0 : return ConvertToB8G8R8A8_Scalar(aSurface);
52 : }
53 :
54 : already_AddRefed<DataSourceSurface>
55 0 : FilterProcessing::ApplyBlending(DataSourceSurface* aInput1, DataSourceSurface* aInput2,
56 : BlendMode aBlendMode)
57 : {
58 0 : if (Factory::HasSSE2()) {
59 : #ifdef USE_SSE2
60 0 : return ApplyBlending_SSE2(aInput1, aInput2, aBlendMode);
61 : #endif
62 : }
63 0 : return nullptr;
64 : }
65 :
66 : void
67 0 : FilterProcessing::ApplyMorphologyHorizontal(uint8_t* aSourceData, int32_t aSourceStride,
68 : uint8_t* aDestData, int32_t aDestStride,
69 : const IntRect& aDestRect, int32_t aRadius,
70 : MorphologyOperator aOp)
71 : {
72 0 : if (Factory::HasSSE2()) {
73 : #ifdef USE_SSE2
74 : ApplyMorphologyHorizontal_SSE2(
75 0 : aSourceData, aSourceStride, aDestData, aDestStride, aDestRect, aRadius, aOp);
76 : #endif
77 : } else {
78 : ApplyMorphologyHorizontal_Scalar(
79 0 : aSourceData, aSourceStride, aDestData, aDestStride, aDestRect, aRadius, aOp);
80 : }
81 0 : }
82 :
83 : void
84 0 : FilterProcessing::ApplyMorphologyVertical(uint8_t* aSourceData, int32_t aSourceStride,
85 : uint8_t* aDestData, int32_t aDestStride,
86 : const IntRect& aDestRect, int32_t aRadius,
87 : MorphologyOperator aOp)
88 : {
89 0 : if (Factory::HasSSE2()) {
90 : #ifdef USE_SSE2
91 : ApplyMorphologyVertical_SSE2(
92 0 : aSourceData, aSourceStride, aDestData, aDestStride, aDestRect, aRadius, aOp);
93 : #endif
94 : } else {
95 : ApplyMorphologyVertical_Scalar(
96 0 : aSourceData, aSourceStride, aDestData, aDestStride, aDestRect, aRadius, aOp);
97 : }
98 0 : }
99 :
100 : already_AddRefed<DataSourceSurface>
101 0 : FilterProcessing::ApplyColorMatrix(DataSourceSurface* aInput, const Matrix5x4 &aMatrix)
102 : {
103 0 : if (Factory::HasSSE2()) {
104 : #ifdef USE_SSE2
105 0 : return ApplyColorMatrix_SSE2(aInput, aMatrix);
106 : #endif
107 : }
108 0 : return ApplyColorMatrix_Scalar(aInput, aMatrix);
109 : }
110 :
111 : void
112 0 : FilterProcessing::ApplyComposition(DataSourceSurface* aSource, DataSourceSurface* aDest,
113 : CompositeOperator aOperator)
114 : {
115 0 : if (Factory::HasSSE2()) {
116 : #ifdef USE_SSE2
117 0 : ApplyComposition_SSE2(aSource, aDest, aOperator);
118 : #endif
119 : } else {
120 0 : ApplyComposition_Scalar(aSource, aDest, aOperator);
121 : }
122 0 : }
123 :
124 : void
125 0 : FilterProcessing::SeparateColorChannels(DataSourceSurface* aSource,
126 : RefPtr<DataSourceSurface>& aChannel0,
127 : RefPtr<DataSourceSurface>& aChannel1,
128 : RefPtr<DataSourceSurface>& aChannel2,
129 : RefPtr<DataSourceSurface>& aChannel3)
130 : {
131 0 : IntSize size = aSource->GetSize();
132 0 : aChannel0 = Factory::CreateDataSourceSurface(size, SurfaceFormat::A8);
133 0 : aChannel1 = Factory::CreateDataSourceSurface(size, SurfaceFormat::A8);
134 0 : aChannel2 = Factory::CreateDataSourceSurface(size, SurfaceFormat::A8);
135 0 : aChannel3 = Factory::CreateDataSourceSurface(size, SurfaceFormat::A8);
136 0 : if (MOZ2D_WARN_IF(!(aChannel0 && aChannel1 && aChannel2 && aChannel3))) {
137 0 : return;
138 : }
139 :
140 0 : DataSourceSurface::ScopedMap sourceMap(aSource, DataSourceSurface::READ);
141 0 : DataSourceSurface::ScopedMap channel0Map(aChannel0, DataSourceSurface::WRITE);
142 0 : DataSourceSurface::ScopedMap channel1Map(aChannel1, DataSourceSurface::WRITE);
143 0 : DataSourceSurface::ScopedMap channel2Map(aChannel2, DataSourceSurface::WRITE);
144 0 : DataSourceSurface::ScopedMap channel3Map(aChannel3, DataSourceSurface::WRITE);
145 0 : if (MOZ2D_WARN_IF(!(sourceMap.IsMapped() &&
146 : channel0Map.IsMapped() && channel1Map.IsMapped() &&
147 : channel2Map.IsMapped() && channel3Map.IsMapped()))) {
148 0 : return;
149 : }
150 0 : uint8_t* sourceData = sourceMap.GetData();
151 0 : int32_t sourceStride = sourceMap.GetStride();
152 0 : uint8_t* channel0Data = channel0Map.GetData();
153 0 : uint8_t* channel1Data = channel1Map.GetData();
154 0 : uint8_t* channel2Data = channel2Map.GetData();
155 0 : uint8_t* channel3Data = channel3Map.GetData();
156 0 : int32_t channelStride = channel0Map.GetStride();
157 :
158 0 : if (Factory::HasSSE2()) {
159 : #ifdef USE_SSE2
160 0 : SeparateColorChannels_SSE2(size, sourceData, sourceStride, channel0Data, channel1Data, channel2Data, channel3Data, channelStride);
161 : #endif
162 : } else {
163 0 : SeparateColorChannels_Scalar(size, sourceData, sourceStride, channel0Data, channel1Data, channel2Data, channel3Data, channelStride);
164 : }
165 : }
166 :
167 : already_AddRefed<DataSourceSurface>
168 0 : FilterProcessing::CombineColorChannels(DataSourceSurface* aChannel0, DataSourceSurface* aChannel1,
169 : DataSourceSurface* aChannel2, DataSourceSurface* aChannel3)
170 : {
171 0 : IntSize size = aChannel0->GetSize();
172 : RefPtr<DataSourceSurface> result =
173 0 : Factory::CreateDataSourceSurface(size, SurfaceFormat::B8G8R8A8);
174 0 : if (MOZ2D_WARN_IF(!result)) {
175 0 : return nullptr;
176 : }
177 0 : DataSourceSurface::ScopedMap resultMap(result, DataSourceSurface::WRITE);
178 0 : DataSourceSurface::ScopedMap channel0Map(aChannel0, DataSourceSurface::READ);
179 0 : DataSourceSurface::ScopedMap channel1Map(aChannel1, DataSourceSurface::READ);
180 0 : DataSourceSurface::ScopedMap channel2Map(aChannel2, DataSourceSurface::READ);
181 0 : DataSourceSurface::ScopedMap channel3Map(aChannel3, DataSourceSurface::READ);
182 0 : if (MOZ2D_WARN_IF(!(resultMap.IsMapped() &&
183 : channel0Map.IsMapped() && channel1Map.IsMapped() &&
184 : channel2Map.IsMapped() && channel3Map.IsMapped()))) {
185 0 : return nullptr;
186 : }
187 0 : int32_t resultStride = resultMap.GetStride();
188 0 : uint8_t* resultData = resultMap.GetData();
189 0 : int32_t channelStride = channel0Map.GetStride();
190 0 : uint8_t* channel0Data = channel0Map.GetData();
191 0 : uint8_t* channel1Data = channel1Map.GetData();
192 0 : uint8_t* channel2Data = channel2Map.GetData();
193 0 : uint8_t* channel3Data = channel3Map.GetData();
194 :
195 0 : if (Factory::HasSSE2()) {
196 : #ifdef USE_SSE2
197 0 : CombineColorChannels_SSE2(size, resultStride, resultData, channelStride, channel0Data, channel1Data, channel2Data, channel3Data);
198 : #endif
199 : } else {
200 0 : CombineColorChannels_Scalar(size, resultStride, resultData, channelStride, channel0Data, channel1Data, channel2Data, channel3Data);
201 : }
202 :
203 0 : return result.forget();
204 : }
205 :
206 : void
207 0 : FilterProcessing::DoPremultiplicationCalculation(const IntSize& aSize,
208 : uint8_t* aTargetData, int32_t aTargetStride,
209 : uint8_t* aSourceData, int32_t aSourceStride)
210 : {
211 0 : if (Factory::HasSSE2()) {
212 : #ifdef USE_SSE2
213 : DoPremultiplicationCalculation_SSE2(
214 0 : aSize, aTargetData, aTargetStride, aSourceData, aSourceStride);
215 : #endif
216 : } else {
217 : DoPremultiplicationCalculation_Scalar(
218 0 : aSize, aTargetData, aTargetStride, aSourceData, aSourceStride);
219 : }
220 0 : }
221 :
222 : void
223 0 : FilterProcessing::DoUnpremultiplicationCalculation(const IntSize& aSize,
224 : uint8_t* aTargetData, int32_t aTargetStride,
225 : uint8_t* aSourceData, int32_t aSourceStride)
226 : {
227 0 : if (Factory::HasSSE2()) {
228 : #ifdef USE_SSE2
229 : DoUnpremultiplicationCalculation_SSE2(
230 0 : aSize, aTargetData, aTargetStride, aSourceData, aSourceStride);
231 : #endif
232 : } else {
233 : DoUnpremultiplicationCalculation_Scalar(
234 0 : aSize, aTargetData, aTargetStride, aSourceData, aSourceStride);
235 : }
236 0 : }
237 :
238 : already_AddRefed<DataSourceSurface>
239 0 : FilterProcessing::RenderTurbulence(const IntSize &aSize, const Point &aOffset, const Size &aBaseFrequency,
240 : int32_t aSeed, int aNumOctaves, TurbulenceType aType, bool aStitch, const Rect &aTileRect)
241 : {
242 0 : if (Factory::HasSSE2()) {
243 : #ifdef USE_SSE2
244 0 : return RenderTurbulence_SSE2(aSize, aOffset, aBaseFrequency, aSeed, aNumOctaves, aType, aStitch, aTileRect);
245 : #endif
246 : }
247 0 : return RenderTurbulence_Scalar(aSize, aOffset, aBaseFrequency, aSeed, aNumOctaves, aType, aStitch, aTileRect);
248 : }
249 :
250 : already_AddRefed<DataSourceSurface>
251 0 : FilterProcessing::ApplyArithmeticCombine(DataSourceSurface* aInput1, DataSourceSurface* aInput2, Float aK1, Float aK2, Float aK3, Float aK4)
252 : {
253 0 : if (Factory::HasSSE2()) {
254 : #ifdef USE_SSE2
255 0 : return ApplyArithmeticCombine_SSE2(aInput1, aInput2, aK1, aK2, aK3, aK4);
256 : #endif
257 : }
258 0 : return ApplyArithmeticCombine_Scalar(aInput1, aInput2, aK1, aK2, aK3, aK4);
259 : }
260 :
261 : } // namespace gfx
262 : } // namespace mozilla
|