static void drawPath(const SkPath *path, const SkPaint* paint, SkBitmap& bitmap, float left, float top, float offset, uint32_t width, uint32_t height) { initBitmap(bitmap, width, height); SkPaint pathPaint(*paint); initPaint(pathPaint); SkCanvas canvas(bitmap); canvas.translate(-left + offset, -top + offset); canvas.drawPath(*path, pathPaint); }
void FETurbulence::apply() { if (hasResult()) return; ByteArray* pixelArray = createUnmultipliedImageResult(); if (!pixelArray) return; if (absolutePaintRect().isEmpty()) return; PaintingData paintingData(m_seed, roundedIntSize(filterPrimitiveSubregion().size())); initPaint(paintingData); #if ENABLE(PARALLEL_JOBS) 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) { 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 sequential mode if there is no room for a new thread or the paint area is too small #endif // ENABLE(PARALLEL_JOBS) fillRegion(pixelArray, paintingData, 0, absolutePaintRect().height()); }
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); }