FilterProcessing.cpp (6386B)
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/. */ 6 7 #include "FilterProcessing.h" 8 #include "Logging.h" 9 #include "Swizzle.h" 10 11 namespace mozilla { 12 namespace gfx { 13 14 already_AddRefed<DataSourceSurface> FilterProcessing::ExtractAlpha( 15 DataSourceSurface* aSource) { 16 IntSize size = aSource->GetSize(); 17 RefPtr<DataSourceSurface> alpha = 18 Factory::CreateDataSourceSurface(size, SurfaceFormat::A8); 19 if (MOZ2D_WARN_IF(!alpha)) { 20 return nullptr; 21 } 22 23 DataSourceSurface::ScopedMap sourceMap(aSource, DataSourceSurface::READ); 24 DataSourceSurface::ScopedMap alphaMap(alpha, DataSourceSurface::WRITE); 25 if (MOZ2D_WARN_IF(!sourceMap.IsMapped() || !alphaMap.IsMapped())) { 26 return nullptr; 27 } 28 29 uint8_t* sourceData = sourceMap.GetData(); 30 int32_t sourceStride = sourceMap.GetStride(); 31 uint8_t* alphaData = alphaMap.GetData(); 32 int32_t alphaStride = alphaMap.GetStride(); 33 34 if (Factory::HasSSE2()) { 35 #ifdef USE_SSE2 36 ExtractAlpha_SSE2(size, sourceData, sourceStride, alphaData, alphaStride); 37 #endif 38 } else { 39 ExtractAlpha_Scalar(size, sourceData, sourceStride, alphaData, alphaStride); 40 } 41 42 return alpha.forget(); 43 } 44 45 already_AddRefed<DataSourceSurface> FilterProcessing::ConvertToB8G8R8A8( 46 SourceSurface* aSurface) { 47 if (Factory::HasSSE2()) { 48 #ifdef USE_SSE2 49 return ConvertToB8G8R8A8_SSE2(aSurface); 50 #endif 51 } 52 return ConvertToB8G8R8A8_Scalar(aSurface); 53 } 54 55 already_AddRefed<DataSourceSurface> FilterProcessing::ApplyBlending( 56 DataSourceSurface* aInput1, DataSourceSurface* aInput2, 57 BlendMode aBlendMode) { 58 if (Factory::HasSSE2()) { 59 #ifdef USE_SSE2 60 return ApplyBlending_SSE2(aInput1, aInput2, aBlendMode); 61 #endif 62 } 63 return nullptr; 64 } 65 66 void FilterProcessing::ApplyMorphologyHorizontal( 67 const uint8_t* aSourceData, int32_t aSourceStride, uint8_t* aDestData, 68 int32_t aDestStride, const IntRect& aDestRect, int32_t aRadius, 69 MorphologyOperator aOp) { 70 if (Factory::HasSSE2()) { 71 #ifdef USE_SSE2 72 ApplyMorphologyHorizontal_SSE2(aSourceData, aSourceStride, aDestData, 73 aDestStride, aDestRect, aRadius, aOp); 74 #endif 75 } else { 76 ApplyMorphologyHorizontal_Scalar(aSourceData, aSourceStride, aDestData, 77 aDestStride, aDestRect, aRadius, aOp); 78 } 79 } 80 81 void FilterProcessing::ApplyMorphologyVertical( 82 const uint8_t* aSourceData, int32_t aSourceStride, uint8_t* aDestData, 83 int32_t aDestStride, const IntRect& aDestRect, int32_t aRadius, 84 MorphologyOperator aOp) { 85 if (Factory::HasSSE2()) { 86 #ifdef USE_SSE2 87 ApplyMorphologyVertical_SSE2(aSourceData, aSourceStride, aDestData, 88 aDestStride, aDestRect, aRadius, aOp); 89 #endif 90 } else { 91 ApplyMorphologyVertical_Scalar(aSourceData, aSourceStride, aDestData, 92 aDestStride, aDestRect, aRadius, aOp); 93 } 94 } 95 96 already_AddRefed<DataSourceSurface> FilterProcessing::ApplyColorMatrix( 97 DataSourceSurface* aInput, const Matrix5x4& aMatrix) { 98 if (Factory::HasSSE2()) { 99 #ifdef USE_SSE2 100 return ApplyColorMatrix_SSE2(aInput, aMatrix); 101 #endif 102 } 103 return ApplyColorMatrix_Scalar(aInput, aMatrix); 104 } 105 106 void FilterProcessing::ApplyComposition(DataSourceSurface* aSource, 107 DataSourceSurface* aDest, 108 CompositeOperator aOperator) { 109 if (Factory::HasSSE2()) { 110 #ifdef USE_SSE2 111 ApplyComposition_SSE2(aSource, aDest, aOperator); 112 #endif 113 } else { 114 ApplyComposition_Scalar(aSource, aDest, aOperator); 115 } 116 } 117 118 void FilterProcessing::DoPremultiplicationCalculation( 119 const IntSize& aSize, uint8_t* aTargetData, int32_t aTargetStride, 120 const uint8_t* aSourceData, int32_t aSourceStride) { 121 PremultiplyData(aSourceData, aSourceStride, SurfaceFormat::B8G8R8A8, 122 aTargetData, aTargetStride, SurfaceFormat::B8G8R8A8, aSize); 123 } 124 125 void FilterProcessing::DoUnpremultiplicationCalculation( 126 const IntSize& aSize, uint8_t* aTargetData, int32_t aTargetStride, 127 const uint8_t* aSourceData, int32_t aSourceStride) { 128 UnpremultiplyData(aSourceData, aSourceStride, SurfaceFormat::B8G8R8A8, 129 aTargetData, aTargetStride, SurfaceFormat::B8G8R8A8, aSize); 130 } 131 132 void FilterProcessing::DoOpacityCalculation( 133 const IntSize& aSize, uint8_t* aTargetData, int32_t aTargetStride, 134 const uint8_t* aSourceData, int32_t aSourceStride, Float aValue) { 135 if (Factory::HasSSE2()) { 136 #ifdef USE_SSE2 137 DoOpacityCalculation_SSE2(aSize, aTargetData, aTargetStride, aSourceData, 138 aSourceStride, aValue); 139 #endif 140 } else { 141 DoOpacityCalculation_Scalar(aSize, aTargetData, aTargetStride, aSourceData, 142 aSourceStride, aValue); 143 } 144 } 145 146 void FilterProcessing::DoOpacityCalculationA8( 147 const IntSize& aSize, uint8_t* aTargetData, int32_t aTargetStride, 148 const uint8_t* aSourceData, int32_t aSourceStride, Float aValue) { 149 DoOpacityCalculationA8_Scalar(aSize, aTargetData, aTargetStride, aSourceData, 150 aSourceStride, aValue); 151 } 152 153 already_AddRefed<DataSourceSurface> FilterProcessing::RenderTurbulence( 154 const IntSize& aSize, const Point& aOffset, const Size& aBaseFrequency, 155 int32_t aSeed, int aNumOctaves, TurbulenceType aType, bool aStitch, 156 const Rect& aTileRect) { 157 if (Factory::HasSSE2()) { 158 #ifdef USE_SSE2 159 return RenderTurbulence_SSE2(aSize, aOffset, aBaseFrequency, aSeed, 160 aNumOctaves, aType, aStitch, aTileRect); 161 #endif 162 } 163 return RenderTurbulence_Scalar(aSize, aOffset, aBaseFrequency, aSeed, 164 aNumOctaves, aType, aStitch, aTileRect); 165 } 166 167 already_AddRefed<DataSourceSurface> FilterProcessing::ApplyArithmeticCombine( 168 DataSourceSurface* aInput1, DataSourceSurface* aInput2, Float aK1, 169 Float aK2, Float aK3, Float aK4) { 170 if (Factory::HasSSE2()) { 171 #ifdef USE_SSE2 172 return ApplyArithmeticCombine_SSE2(aInput1, aInput2, aK1, aK2, aK3, aK4); 173 #endif 174 } 175 return ApplyArithmeticCombine_Scalar(aInput1, aInput2, aK1, aK2, aK3, aK4); 176 } 177 178 } // namespace gfx 179 } // namespace mozilla