1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include "FilterProcessing.h"
13 already_AddRefed
<DataSourceSurface
> FilterProcessing::ExtractAlpha(
14 DataSourceSurface
* aSource
) {
15 IntSize size
= aSource
->GetSize();
16 RefPtr
<DataSourceSurface
> alpha
=
17 Factory::CreateDataSourceSurface(size
, SurfaceFormat::A8
);
18 if (MOZ2D_WARN_IF(!alpha
)) {
22 DataSourceSurface::ScopedMap
sourceMap(aSource
, DataSourceSurface::READ
);
23 DataSourceSurface::ScopedMap
alphaMap(alpha
, DataSourceSurface::WRITE
);
24 if (MOZ2D_WARN_IF(!sourceMap
.IsMapped() || !alphaMap
.IsMapped())) {
28 uint8_t* sourceData
= sourceMap
.GetData();
29 int32_t sourceStride
= sourceMap
.GetStride();
30 uint8_t* alphaData
= alphaMap
.GetData();
31 int32_t alphaStride
= alphaMap
.GetStride();
33 if (Factory::HasSSE2()) {
35 ExtractAlpha_SSE2(size
, sourceData
, sourceStride
, alphaData
, alphaStride
);
38 ExtractAlpha_Scalar(size
, sourceData
, sourceStride
, alphaData
, alphaStride
);
41 return alpha
.forget();
44 already_AddRefed
<DataSourceSurface
> FilterProcessing::ConvertToB8G8R8A8(
45 SourceSurface
* aSurface
) {
46 if (Factory::HasSSE2()) {
48 return ConvertToB8G8R8A8_SSE2(aSurface
);
51 return ConvertToB8G8R8A8_Scalar(aSurface
);
54 already_AddRefed
<DataSourceSurface
> FilterProcessing::ApplyBlending(
55 DataSourceSurface
* aInput1
, DataSourceSurface
* aInput2
,
56 BlendMode aBlendMode
) {
57 if (Factory::HasSSE2()) {
59 return ApplyBlending_SSE2(aInput1
, aInput2
, aBlendMode
);
65 void FilterProcessing::ApplyMorphologyHorizontal(
66 uint8_t* aSourceData
, int32_t aSourceStride
, uint8_t* aDestData
,
67 int32_t aDestStride
, const IntRect
& aDestRect
, int32_t aRadius
,
68 MorphologyOperator aOp
) {
69 if (Factory::HasSSE2()) {
71 ApplyMorphologyHorizontal_SSE2(aSourceData
, aSourceStride
, aDestData
,
72 aDestStride
, aDestRect
, aRadius
, aOp
);
75 ApplyMorphologyHorizontal_Scalar(aSourceData
, aSourceStride
, aDestData
,
76 aDestStride
, aDestRect
, aRadius
, aOp
);
80 void FilterProcessing::ApplyMorphologyVertical(
81 uint8_t* aSourceData
, int32_t aSourceStride
, uint8_t* aDestData
,
82 int32_t aDestStride
, const IntRect
& aDestRect
, int32_t aRadius
,
83 MorphologyOperator aOp
) {
84 if (Factory::HasSSE2()) {
86 ApplyMorphologyVertical_SSE2(aSourceData
, aSourceStride
, aDestData
,
87 aDestStride
, aDestRect
, aRadius
, aOp
);
90 ApplyMorphologyVertical_Scalar(aSourceData
, aSourceStride
, aDestData
,
91 aDestStride
, aDestRect
, aRadius
, aOp
);
95 already_AddRefed
<DataSourceSurface
> FilterProcessing::ApplyColorMatrix(
96 DataSourceSurface
* aInput
, const Matrix5x4
& aMatrix
) {
97 if (Factory::HasSSE2()) {
99 return ApplyColorMatrix_SSE2(aInput
, aMatrix
);
102 return ApplyColorMatrix_Scalar(aInput
, aMatrix
);
105 void FilterProcessing::ApplyComposition(DataSourceSurface
* aSource
,
106 DataSourceSurface
* aDest
,
107 CompositeOperator aOperator
) {
108 if (Factory::HasSSE2()) {
110 ApplyComposition_SSE2(aSource
, aDest
, aOperator
);
113 ApplyComposition_Scalar(aSource
, aDest
, aOperator
);
117 void FilterProcessing::SeparateColorChannels(
118 DataSourceSurface
* aSource
, RefPtr
<DataSourceSurface
>& aChannel0
,
119 RefPtr
<DataSourceSurface
>& aChannel1
, RefPtr
<DataSourceSurface
>& aChannel2
,
120 RefPtr
<DataSourceSurface
>& aChannel3
) {
121 IntSize size
= aSource
->GetSize();
122 aChannel0
= Factory::CreateDataSourceSurface(size
, SurfaceFormat::A8
);
123 aChannel1
= Factory::CreateDataSourceSurface(size
, SurfaceFormat::A8
);
124 aChannel2
= Factory::CreateDataSourceSurface(size
, SurfaceFormat::A8
);
125 aChannel3
= Factory::CreateDataSourceSurface(size
, SurfaceFormat::A8
);
126 if (MOZ2D_WARN_IF(!(aChannel0
&& aChannel1
&& aChannel2
&& aChannel3
))) {
130 DataSourceSurface::ScopedMap
sourceMap(aSource
, DataSourceSurface::READ
);
131 DataSourceSurface::ScopedMap
channel0Map(aChannel0
, DataSourceSurface::WRITE
);
132 DataSourceSurface::ScopedMap
channel1Map(aChannel1
, DataSourceSurface::WRITE
);
133 DataSourceSurface::ScopedMap
channel2Map(aChannel2
, DataSourceSurface::WRITE
);
134 DataSourceSurface::ScopedMap
channel3Map(aChannel3
, DataSourceSurface::WRITE
);
135 if (MOZ2D_WARN_IF(!(sourceMap
.IsMapped() && channel0Map
.IsMapped() &&
136 channel1Map
.IsMapped() && channel2Map
.IsMapped() &&
137 channel3Map
.IsMapped()))) {
140 uint8_t* sourceData
= sourceMap
.GetData();
141 int32_t sourceStride
= sourceMap
.GetStride();
142 uint8_t* channel0Data
= channel0Map
.GetData();
143 uint8_t* channel1Data
= channel1Map
.GetData();
144 uint8_t* channel2Data
= channel2Map
.GetData();
145 uint8_t* channel3Data
= channel3Map
.GetData();
146 int32_t channelStride
= channel0Map
.GetStride();
148 if (Factory::HasSSE2()) {
150 SeparateColorChannels_SSE2(size
, sourceData
, sourceStride
, channel0Data
,
151 channel1Data
, channel2Data
, channel3Data
,
155 SeparateColorChannels_Scalar(size
, sourceData
, sourceStride
, channel0Data
,
156 channel1Data
, channel2Data
, channel3Data
,
161 already_AddRefed
<DataSourceSurface
> FilterProcessing::CombineColorChannels(
162 DataSourceSurface
* aChannel0
, DataSourceSurface
* aChannel1
,
163 DataSourceSurface
* aChannel2
, DataSourceSurface
* aChannel3
) {
164 IntSize size
= aChannel0
->GetSize();
165 RefPtr
<DataSourceSurface
> result
=
166 Factory::CreateDataSourceSurface(size
, SurfaceFormat::B8G8R8A8
);
167 if (MOZ2D_WARN_IF(!result
)) {
170 DataSourceSurface::ScopedMap
resultMap(result
, DataSourceSurface::WRITE
);
171 DataSourceSurface::ScopedMap
channel0Map(aChannel0
, DataSourceSurface::READ
);
172 DataSourceSurface::ScopedMap
channel1Map(aChannel1
, DataSourceSurface::READ
);
173 DataSourceSurface::ScopedMap
channel2Map(aChannel2
, DataSourceSurface::READ
);
174 DataSourceSurface::ScopedMap
channel3Map(aChannel3
, DataSourceSurface::READ
);
175 if (MOZ2D_WARN_IF(!(resultMap
.IsMapped() && channel0Map
.IsMapped() &&
176 channel1Map
.IsMapped() && channel2Map
.IsMapped() &&
177 channel3Map
.IsMapped()))) {
180 int32_t resultStride
= resultMap
.GetStride();
181 uint8_t* resultData
= resultMap
.GetData();
182 int32_t channelStride
= channel0Map
.GetStride();
183 uint8_t* channel0Data
= channel0Map
.GetData();
184 uint8_t* channel1Data
= channel1Map
.GetData();
185 uint8_t* channel2Data
= channel2Map
.GetData();
186 uint8_t* channel3Data
= channel3Map
.GetData();
188 if (Factory::HasSSE2()) {
190 CombineColorChannels_SSE2(size
, resultStride
, resultData
, channelStride
,
191 channel0Data
, channel1Data
, channel2Data
,
195 CombineColorChannels_Scalar(size
, resultStride
, resultData
, channelStride
,
196 channel0Data
, channel1Data
, channel2Data
,
200 return result
.forget();
203 void FilterProcessing::DoPremultiplicationCalculation(const IntSize
& aSize
,
204 uint8_t* aTargetData
,
205 int32_t aTargetStride
,
206 uint8_t* aSourceData
,
207 int32_t aSourceStride
) {
208 if (Factory::HasSSE2()) {
210 DoPremultiplicationCalculation_SSE2(aSize
, aTargetData
, aTargetStride
,
211 aSourceData
, aSourceStride
);
214 DoPremultiplicationCalculation_Scalar(aSize
, aTargetData
, aTargetStride
,
215 aSourceData
, aSourceStride
);
219 void FilterProcessing::DoUnpremultiplicationCalculation(const IntSize
& aSize
,
220 uint8_t* aTargetData
,
221 int32_t aTargetStride
,
222 uint8_t* aSourceData
,
223 int32_t aSourceStride
) {
224 if (Factory::HasSSE2()) {
226 DoUnpremultiplicationCalculation_SSE2(aSize
, aTargetData
, aTargetStride
,
227 aSourceData
, aSourceStride
);
230 DoUnpremultiplicationCalculation_Scalar(aSize
, aTargetData
, aTargetStride
,
231 aSourceData
, aSourceStride
);
235 void FilterProcessing::DoOpacityCalculation(
236 const IntSize
& aSize
, uint8_t* aTargetData
, int32_t aTargetStride
,
237 uint8_t* aSourceData
, int32_t aSourceStride
, Float aValue
) {
238 if (Factory::HasSSE2()) {
240 DoOpacityCalculation_SSE2(aSize
, aTargetData
, aTargetStride
, aSourceData
,
241 aSourceStride
, aValue
);
244 DoOpacityCalculation_Scalar(aSize
, aTargetData
, aTargetStride
, aSourceData
,
245 aSourceStride
, aValue
);
249 void FilterProcessing::DoOpacityCalculationA8(
250 const IntSize
& aSize
, uint8_t* aTargetData
, int32_t aTargetStride
,
251 uint8_t* aSourceData
, int32_t aSourceStride
, Float aValue
) {
252 DoOpacityCalculationA8_Scalar(aSize
, aTargetData
, aTargetStride
, aSourceData
,
253 aSourceStride
, aValue
);
256 already_AddRefed
<DataSourceSurface
> FilterProcessing::RenderTurbulence(
257 const IntSize
& aSize
, const Point
& aOffset
, const Size
& aBaseFrequency
,
258 int32_t aSeed
, int aNumOctaves
, TurbulenceType aType
, bool aStitch
,
259 const Rect
& aTileRect
) {
260 if (Factory::HasSSE2()) {
262 return RenderTurbulence_SSE2(aSize
, aOffset
, aBaseFrequency
, aSeed
,
263 aNumOctaves
, aType
, aStitch
, aTileRect
);
266 return RenderTurbulence_Scalar(aSize
, aOffset
, aBaseFrequency
, aSeed
,
267 aNumOctaves
, aType
, aStitch
, aTileRect
);
270 already_AddRefed
<DataSourceSurface
> FilterProcessing::ApplyArithmeticCombine(
271 DataSourceSurface
* aInput1
, DataSourceSurface
* aInput2
, Float aK1
,
272 Float aK2
, Float aK3
, Float aK4
) {
273 if (Factory::HasSSE2()) {
275 return ApplyArithmeticCombine_SSE2(aInput1
, aInput2
, aK1
, aK2
, aK3
, aK4
);
278 return ApplyArithmeticCombine_Scalar(aInput1
, aInput2
, aK1
, aK2
, aK3
, aK4
);
282 } // namespace mozilla