void FEMorphology::platformApplySoftware() { FilterEffect* in = inputEffect(0); Uint8ClampedArray* dstPixelArray = createPremultipliedImageResult(); if (!dstPixelArray) return; setIsAlphaImage(in->isAlphaImage()); if (m_radiusX <= 0 || m_radiusY <= 0) { dstPixelArray->zeroFill(); return; } Filter& filter = this->filter(); int radiusX = static_cast<int>(floorf(filter.applyHorizontalScale(m_radiusX))); int radiusY = static_cast<int>(floorf(filter.applyVerticalScale(m_radiusY))); IntRect effectDrawingRect = requestedRegionOfInputImageData(in->absolutePaintRect()); RefPtr<Uint8ClampedArray> srcPixelArray = in->asPremultipliedImage(effectDrawingRect); PaintingData paintingData; paintingData.srcPixelArray = srcPixelArray.get(); paintingData.dstPixelArray = dstPixelArray; paintingData.width = effectDrawingRect.width(); paintingData.height = effectDrawingRect.height(); paintingData.radiusX = std::min(effectDrawingRect.width() - 1, radiusX); paintingData.radiusY = std::min(effectDrawingRect.height() - 1, radiusY); platformApply(&paintingData); }
void FETurbulence::applySoftware() { Uint8ClampedArray* pixelArray = createUnmultipliedImageResult(); if (!pixelArray) return; if (absolutePaintRect().isEmpty()) { pixelArray->zeroFill(); return; } PaintingData paintingData(m_seed, roundedIntSize(filterPrimitiveSubregion().size())); initPaint(paintingData); int optimalThreadNumber = (absolutePaintRect().width() * absolutePaintRect().height()) / s_minimalRectDimension; if (optimalThreadNumber > 1) { // Initialize parallel jobs ParallelJobs<FillRegionParameters> parallelJobs(&WebCore::FETurbulence::fillRegionWorker, optimalThreadNumber); // Fill the parameter array int i = parallelJobs.numberOfJobs(); if (i > 1) { // Split the job into "stepY"-sized jobs but there a few jobs that need to be slightly larger since // stepY * jobs < total size. These extras are handled by the remainder "jobsWithExtra". const int stepY = absolutePaintRect().height() / i; const int jobsWithExtra = absolutePaintRect().height() % i; int startY = 0; for (; i > 0; --i) { FillRegionParameters& params = parallelJobs.parameter(i-1); params.filter = this; params.pixelArray = pixelArray; params.paintingData = &paintingData; params.startY = startY; startY += i < jobsWithExtra ? stepY + 1 : stepY; params.endY = startY; params.baseFrequencyX = m_baseFrequencyX; params.baseFrequencyY = m_baseFrequencyY; } // Execute parallel jobs parallelJobs.execute(); return; } } // Fallback to single threaded mode if there is no room for a new thread or the paint area is too small. fillRegion(pixelArray, paintingData, 0, absolutePaintRect().height(), m_baseFrequencyX, m_baseFrequencyY); }
void FETurbulence::platformApplySoftware() { Uint8ClampedArray* pixelArray = createUnmultipliedImageResult(); if (!pixelArray) return; if (absolutePaintRect().isEmpty()) { pixelArray->zeroFill(); return; } PaintingData paintingData(m_seed, roundedIntSize(filterPrimitiveSubregion().size())); initPaint(paintingData); int optimalThreadNumber = (absolutePaintRect().width() * absolutePaintRect().height()) / s_minimalRectDimension; if (optimalThreadNumber > 1) { // Initialize parallel jobs WTF::ParallelJobs<FillRegionParameters> parallelJobs(&WebCore::FETurbulence::fillRegionWorker, optimalThreadNumber); // Fill the parameter array int i = parallelJobs.numberOfJobs(); if (i > 1) { int startY = 0; int stepY = absolutePaintRect().height() / i; for (; i > 0; --i) { FillRegionParameters& params = parallelJobs.parameter(i-1); params.filter = this; params.pixelArray = pixelArray; params.paintingData = &paintingData; params.startY = startY; if (i != 1) { params.endY = startY + stepY; startY = startY + stepY; } else params.endY = absolutePaintRect().height(); } // Execute parallel jobs parallelJobs.execute(); return; } } // Fallback to single threaded mode if there is no room for a new thread or the paint area is too small. fillRegion(pixelArray, paintingData, 0, absolutePaintRect().height()); }