Changeset 215069 in webkit
- Timestamp:
- Apr 6, 2017, 5:01:29 PM (8 years ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r215068 r215069 1 2017-04-05 Simon Fraser <simon.fraser@apple.com> 2 3 Use the Accelerate framework to optimize FEColorMatrix operations 4 https://bugs.webkit.org/show_bug.cgi?id=170518 5 6 Reviewed by Tim Horton. 7 8 On macOS and iOS, we can use the Accelerate framework (vImage) to do color matrix 9 math to optimize color matrix, hue rotate, saturation and luminosity to alpha filters. 10 11 Change ImageBuffer::getUnmultipliedImageData() and getPremultipliedImageData() to 12 return the size of the returned Uint8ClampedArray in physical pixels, because we 13 need to pass that to vImage. 14 15 * html/canvas/CanvasRenderingContext2D.cpp: 16 (WebCore::CanvasRenderingContext2D::getImageData): 17 * platform/graphics/ImageBuffer.h: 18 * platform/graphics/cairo/ImageBufferCairo.cpp: 19 (WebCore::ImageBuffer::getUnmultipliedImageData): 20 (WebCore::ImageBuffer::getPremultipliedImageData): 21 * platform/graphics/cg/ImageBufferCG.cpp: 22 (WebCore::ImageBuffer::getUnmultipliedImageData): 23 (WebCore::ImageBuffer::getPremultipliedImageData): 24 * platform/graphics/filters/FEColorMatrix.cpp: 25 (WebCore::effectApplyAccelerated): 26 (WebCore::effectType): 27 (WebCore::FEColorMatrix::platformApplySoftware): 28 * platform/graphics/filters/FEDropShadow.cpp: 29 (WebCore::FEDropShadow::platformApplySoftware): 30 * platform/graphics/win/ImageBufferDirect2D.cpp: 31 (WebCore::ImageBuffer::getUnmultipliedImageData): 32 (WebCore::ImageBuffer::getPremultipliedImageData): 33 1 34 2017-04-04 Simon Fraser <simon.fraser@apple.com> 2 35 -
trunk/Source/WebCore/html/canvas/CanvasRenderingContext2D.cpp
r210828 r215069 2009 2009 return createEmptyImageData(imageDataRect.size()); 2010 2010 2011 auto byteArray = buffer->getUnmultipliedImageData(imageDataRect, coordinateSystem);2011 auto byteArray = buffer->getUnmultipliedImageData(imageDataRect, nullptr, coordinateSystem); 2012 2012 if (!byteArray) { 2013 2013 StringBuilder consoleMessage; -
trunk/Source/WebCore/platform/graphics/ImageBuffer.h
r213598 r215069 105 105 enum CoordinateSystem { LogicalCoordinateSystem, BackingStoreCoordinateSystem }; 106 106 107 RefPtr<Uint8ClampedArray> getUnmultipliedImageData(const IntRect&, CoordinateSystem = LogicalCoordinateSystem) const;108 RefPtr<Uint8ClampedArray> getPremultipliedImageData(const IntRect&, CoordinateSystem = LogicalCoordinateSystem) const;107 RefPtr<Uint8ClampedArray> getUnmultipliedImageData(const IntRect&, IntSize* pixelArrayDimensions = nullptr, CoordinateSystem = LogicalCoordinateSystem) const; 108 RefPtr<Uint8ClampedArray> getPremultipliedImageData(const IntRect&, IntSize* pixelArrayDimensions = nullptr, CoordinateSystem = LogicalCoordinateSystem) const; 109 109 110 110 void putByteArray(Multiply multiplied, Uint8ClampedArray*, const IntSize& sourceSize, const IntRect& sourceRect, const IntPoint& destPoint, CoordinateSystem = LogicalCoordinateSystem); -
trunk/Source/WebCore/platform/graphics/cairo/ImageBufferCairo.cpp
r214450 r215069 434 434 } 435 435 436 RefPtr<Uint8ClampedArray> ImageBuffer::getUnmultipliedImageData(const IntRect& rect, CoordinateSystem coordinateSystem) const436 RefPtr<Uint8ClampedArray> ImageBuffer::getUnmultipliedImageData(const IntRect& rect, IntSize* pixelArrayDimensions, CoordinateSystem coordinateSystem) const 437 437 { 438 438 IntRect logicalRect = logicalUnit(rect, coordinateSystem, m_resolutionScale); 439 439 IntRect backingStoreRect = backingStoreUnit(rect, coordinateSystem, m_resolutionScale); 440 if (pixelArrayDimensions) 441 *pixelArrayDimensions = backingStoreRect.size(); 440 442 return getImageData<Unmultiplied>(backingStoreRect, logicalRect, m_data, m_size, m_logicalSize, m_resolutionScale); 441 443 } 442 444 443 RefPtr<Uint8ClampedArray> ImageBuffer::getPremultipliedImageData(const IntRect& rect, CoordinateSystem coordinateSystem) const445 RefPtr<Uint8ClampedArray> ImageBuffer::getPremultipliedImageData(const IntRect& rect, IntSize* pixelArrayDimensions, CoordinateSystem coordinateSystem) const 444 446 { 445 447 IntRect logicalRect = logicalUnit(rect, coordinateSystem, m_resolutionScale); 446 448 IntRect backingStoreRect = backingStoreUnit(rect, coordinateSystem, m_resolutionScale); 449 if (pixelArrayDimensions) 450 *pixelArrayDimensions = backingStoreRect.size(); 447 451 return getImageData<Premultiplied>(backingStoreRect, logicalRect, m_data, m_size, m_logicalSize, m_resolutionScale); 448 452 } -
trunk/Source/WebCore/platform/graphics/cg/ImageBufferCG.cpp
r213508 r215069 383 383 } 384 384 385 RefPtr<Uint8ClampedArray> ImageBuffer::getUnmultipliedImageData(const IntRect& rect, CoordinateSystem coordinateSystem) const385 RefPtr<Uint8ClampedArray> ImageBuffer::getUnmultipliedImageData(const IntRect& rect, IntSize* pixelArrayDimensions, CoordinateSystem coordinateSystem) const 386 386 { 387 387 if (context().isAcceleratedContext()) … … 392 392 srcRect.scale(m_resolutionScale); 393 393 394 if (pixelArrayDimensions) 395 *pixelArrayDimensions = srcRect.size(); 396 394 397 return m_data.getData(srcRect, internalSize(), context().isAcceleratedContext(), true, 1); 395 398 } 396 399 397 RefPtr<Uint8ClampedArray> ImageBuffer::getPremultipliedImageData(const IntRect& rect, CoordinateSystem coordinateSystem) const400 RefPtr<Uint8ClampedArray> ImageBuffer::getPremultipliedImageData(const IntRect& rect, IntSize* pixelArrayDimensions, CoordinateSystem coordinateSystem) const 398 401 { 399 402 if (context().isAcceleratedContext()) … … 403 406 if (coordinateSystem == LogicalCoordinateSystem) 404 407 srcRect.scale(m_resolutionScale); 408 409 if (pixelArrayDimensions) 410 *pixelArrayDimensions = srcRect.size(); 405 411 406 412 return m_data.getData(srcRect, internalSize(), context().isAcceleratedContext(), false, 1); -
trunk/Source/WebCore/platform/graphics/filters/FEColorMatrix.cpp
r214916 r215069 31 31 #include <wtf/MathExtras.h> 32 32 33 #if USE(ACCELERATE) 34 #include <Accelerate/Accelerate.h> 35 #endif 36 33 37 #define PRINT_FILTER_PERFORMANCE 0 34 38 … … 105 109 } 106 110 111 #if USE(ACCELERATE) 107 112 template<ColorMatrixType filterType> 108 void effectType(Uint8ClampedArray* pixelArray, const Vector<float>& values) 113 bool effectApplyAccelerated(Uint8ClampedArray* pixelArray, const Vector<float>& values, float components[9], IntSize bufferSize) 114 { 115 ASSERT(pixelArray->length() == bufferSize.area().unsafeGet() * 4); 116 117 if (filterType == FECOLORMATRIX_TYPE_MATRIX) { 118 // vImageMatrixMultiply_ARGB8888 takes a 4x4 matrix, if any value in the last column of the FEColorMatrix 5x4 matrix 119 // is not zero, fall back to non-vImage code. 120 if (values[4] != 0 || values[9] != 0 || values[14] != 0 || values[19] != 0) 121 return false; 122 } 123 124 const int32_t divisor = 256; 125 uint8_t* data = pixelArray->data(); 126 127 vImage_Buffer src; 128 src.width = bufferSize.width(); 129 src.height = bufferSize.height(); 130 src.rowBytes = bufferSize.width() * 4; 131 src.data = data; 132 133 vImage_Buffer dest; 134 dest.width = bufferSize.width(); 135 dest.height = bufferSize.height(); 136 dest.rowBytes = bufferSize.width() * 4; 137 dest.data = data; 138 139 switch (filterType) { 140 case FECOLORMATRIX_TYPE_MATRIX: { 141 const int16_t matrix[4 * 4] = { 142 static_cast<int16_t>(roundf(values[ 0] * divisor)), 143 static_cast<int16_t>(roundf(values[ 5] * divisor)), 144 static_cast<int16_t>(roundf(values[10] * divisor)), 145 static_cast<int16_t>(roundf(values[15] * divisor)), 146 147 static_cast<int16_t>(roundf(values[ 1] * divisor)), 148 static_cast<int16_t>(roundf(values[ 6] * divisor)), 149 static_cast<int16_t>(roundf(values[11] * divisor)), 150 static_cast<int16_t>(roundf(values[16] * divisor)), 151 152 static_cast<int16_t>(roundf(values[ 2] * divisor)), 153 static_cast<int16_t>(roundf(values[ 7] * divisor)), 154 static_cast<int16_t>(roundf(values[12] * divisor)), 155 static_cast<int16_t>(roundf(values[17] * divisor)), 156 157 static_cast<int16_t>(roundf(values[ 3] * divisor)), 158 static_cast<int16_t>(roundf(values[ 8] * divisor)), 159 static_cast<int16_t>(roundf(values[13] * divisor)), 160 static_cast<int16_t>(roundf(values[18] * divisor)), 161 }; 162 vImageMatrixMultiply_ARGB8888(&src, &dest, matrix, divisor, nullptr, nullptr, kvImageNoFlags); 163 break; 164 } 165 166 case FECOLORMATRIX_TYPE_SATURATE: 167 case FECOLORMATRIX_TYPE_HUEROTATE: { 168 const int16_t matrix[4 * 4] = { 169 static_cast<int16_t>(roundf(components[0] * divisor)), 170 static_cast<int16_t>(roundf(components[3] * divisor)), 171 static_cast<int16_t>(roundf(components[6] * divisor)), 172 0, 173 174 static_cast<int16_t>(roundf(components[1] * divisor)), 175 static_cast<int16_t>(roundf(components[4] * divisor)), 176 static_cast<int16_t>(roundf(components[7] * divisor)), 177 0, 178 179 static_cast<int16_t>(roundf(components[2] * divisor)), 180 static_cast<int16_t>(roundf(components[5] * divisor)), 181 static_cast<int16_t>(roundf(components[8] * divisor)), 182 0, 183 184 0, 185 0, 186 0, 187 divisor, 188 }; 189 vImageMatrixMultiply_ARGB8888(&src, &dest, matrix, divisor, nullptr, nullptr, kvImageNoFlags); 190 break; 191 } 192 case FECOLORMATRIX_TYPE_LUMINANCETOALPHA: { 193 const int16_t matrix[4 * 4] = { 194 0, 195 0, 196 0, 197 static_cast<int16_t>(roundf(0.2125 * divisor)), 198 199 0, 200 0, 201 0, 202 static_cast<int16_t>(roundf(0.7154 * divisor)), 203 204 0, 205 0, 206 0, 207 static_cast<int16_t>(roundf(0.0721 * divisor)), 208 209 0, 210 0, 211 0, 212 0, 213 }; 214 vImageMatrixMultiply_ARGB8888(&src, &dest, matrix, divisor, nullptr, nullptr, kvImageNoFlags); 215 break; 216 } 217 } 218 219 return true; 220 } 221 #endif 222 223 template<ColorMatrixType filterType> 224 void effectType(Uint8ClampedArray* pixelArray, const Vector<float>& values, IntSize bufferSize) 109 225 { 110 226 float components[9]; … … 116 232 117 233 unsigned pixelArrayLength = pixelArray->length(); 234 235 #if USE(ACCELERATE) 236 if (effectApplyAccelerated<filterType>(pixelArray, values, components, bufferSize)) 237 return; 238 #else 239 UNUSED_PARAM(bufferSize); 240 #endif 118 241 119 242 switch (filterType) { … … 180 303 181 304 IntRect imageRect(IntPoint(), resultImage->logicalSize()); 182 RefPtr<Uint8ClampedArray> pixelArray = resultImage->getUnmultipliedImageData(imageRect); 305 IntSize pixelArrayDimensions; 306 RefPtr<Uint8ClampedArray> pixelArray = resultImage->getUnmultipliedImageData(imageRect, &pixelArrayDimensions); 183 307 Vector<float> values = normalizedFloats(m_values); 184 308 … … 187 311 break; 188 312 case FECOLORMATRIX_TYPE_MATRIX: 189 effectType<FECOLORMATRIX_TYPE_MATRIX>(pixelArray.get(), values );313 effectType<FECOLORMATRIX_TYPE_MATRIX>(pixelArray.get(), values, pixelArrayDimensions); 190 314 break; 191 315 case FECOLORMATRIX_TYPE_SATURATE: 192 effectType<FECOLORMATRIX_TYPE_SATURATE>(pixelArray.get(), values );316 effectType<FECOLORMATRIX_TYPE_SATURATE>(pixelArray.get(), values, pixelArrayDimensions); 193 317 break; 194 318 case FECOLORMATRIX_TYPE_HUEROTATE: 195 effectType<FECOLORMATRIX_TYPE_HUEROTATE>(pixelArray.get(), values );319 effectType<FECOLORMATRIX_TYPE_HUEROTATE>(pixelArray.get(), values, pixelArrayDimensions); 196 320 break; 197 321 case FECOLORMATRIX_TYPE_LUMINANCETOALPHA: 198 effectType<FECOLORMATRIX_TYPE_LUMINANCETOALPHA>(pixelArray.get(), values );322 effectType<FECOLORMATRIX_TYPE_LUMINANCETOALPHA>(pixelArray.get(), values, pixelArrayDimensions); 199 323 setIsAlphaImage(true); 200 324 break; -
trunk/Source/WebCore/platform/graphics/filters/FEDropShadow.cpp
r208058 r215069 100 100 // TODO: Direct pixel access to ImageBuffer would avoid copying the ImageData. 101 101 IntRect shadowArea(IntPoint(), resultImage->internalSize()); 102 RefPtr<Uint8ClampedArray> srcPixelArray = resultImage->getPremultipliedImageData(shadowArea, ImageBuffer::BackingStoreCoordinateSystem);102 RefPtr<Uint8ClampedArray> srcPixelArray = resultImage->getPremultipliedImageData(shadowArea, nullptr, ImageBuffer::BackingStoreCoordinateSystem); 103 103 104 104 contextShadow.blurLayerImage(srcPixelArray->data(), shadowArea.size(), 4 * shadowArea.size().width()); -
trunk/Source/WebCore/platform/graphics/win/ImageBufferDirect2D.cpp
r213412 r215069 216 216 } 217 217 218 RefPtr<Uint8ClampedArray> ImageBuffer::getUnmultipliedImageData(const IntRect& rect, CoordinateSystem coordinateSystem) const218 RefPtr<Uint8ClampedArray> ImageBuffer::getUnmultipliedImageData(const IntRect& rect, IntSize* pixelArrayDimensions, CoordinateSystem coordinateSystem) const 219 219 { 220 220 if (context().isAcceleratedContext()) … … 225 225 srcRect.scale(m_resolutionScale); 226 226 227 if (pixelArrayDimensions) 228 *pixelArrayDimensions = srcRect.size(); 229 227 230 return m_data.getData(srcRect, internalSize(), context().isAcceleratedContext(), true, 1); 228 231 } 229 232 230 RefPtr<Uint8ClampedArray> ImageBuffer::getPremultipliedImageData(const IntRect& rect, CoordinateSystem coordinateSystem) const233 RefPtr<Uint8ClampedArray> ImageBuffer::getPremultipliedImageData(const IntRect& rect, IntSize* pixelArrayDimensions, CoordinateSystem coordinateSystem) const 231 234 { 232 235 if (context().isAcceleratedContext()) … … 236 239 if (coordinateSystem == LogicalCoordinateSystem) 237 240 srcRect.scale(m_resolutionScale); 241 242 if (pixelArrayDimensions) 243 *pixelArrayDimensions = srcRect.size(); 238 244 239 245 return m_data.getData(srcRect, internalSize(), context().isAcceleratedContext(), false, 1);
Note:
See TracChangeset
for help on using the changeset viewer.