// recompiles a lot less painful.
SkConvolutionProcs simd;
- fConvolutionProcs = &simd;
+ sk_bzero(&simd, sizeof(simd));
- fConvolutionProcs->fExtraHorizontalReads = 0;
- fConvolutionProcs->fConvolveVertically = NULL;
- fConvolutionProcs->fConvolve4RowsHorizontally = NULL;
- fConvolutionProcs->fConvolveHorizontally = NULL;
- fConvolutionProcs->fApplySIMDPadding = NULL;
-
- this->platformConvolutionProcs();
+ this->platformConvolutionProcs(&simd);
// STEP 1: Highest quality direct scale?
SkBitmapScaler::RESIZE_BEST,
dest_width,
dest_height,
- fConvolutionProcs)) {
+ simd)) {
// we failed to create fScaledBitmap, so just return and let
// the scanline proc handle it.
return;
SkFixed fFilterOneX;
SkFixed fFilterOneY;
- SkConvolutionProcs* fConvolutionProcs; // possiblyScaleImage
-
SkPMColor fPaintPMColor; // chooseProcs - A8 config
SkFixed fInvSx; // chooseProcs
SkFixed fInvKy; // chooseProcs
if we have SIMD versions of them.
*/
- void platformConvolutionProcs();
+ void platformConvolutionProcs(SkConvolutionProcs*);
/** Given the byte size of the index buffer to be passed to the matrix proc,
return the maximum number of resulting pixels that can be computed
int srcFullWidth, int srcFullHeight,
int destWidth, int destHeight,
const SkIRect& destSubset,
- SkConvolutionProcs* convolveProcs);
+ const SkConvolutionProcs& convolveProcs);
~SkResizeFilter() {
SkDELETE( fBitmapFilter );
}
int destSubsetLo, int destSubsetSize,
float scale,
SkConvolutionFilter1D* output,
- SkConvolutionProcs* convolveProcs);
+ const SkConvolutionProcs& convolveProcs);
SkConvolutionFilter1D fXFilter;
SkConvolutionFilter1D fYFilter;
int srcFullWidth, int srcFullHeight,
int destWidth, int destHeight,
const SkIRect& destSubset,
- SkConvolutionProcs* convolveProcs) {
+ const SkConvolutionProcs& convolveProcs) {
// method will only ever refer to an "algorithm method".
SkASSERT((SkBitmapScaler::RESIZE_FIRST_ALGORITHM_METHOD <= method) &&
int destSubsetLo, int destSubsetSize,
float scale,
SkConvolutionFilter1D* output,
- SkConvolutionProcs* convolveProcs) {
+ const SkConvolutionProcs& convolveProcs) {
int destSubsetHi = destSubsetLo + destSubsetSize; // [lo, hi)
// When we're doing a magnification, the scale will be larger than one. This
static_cast<int>(fixedFilterValues.count()));
}
- if (convolveProcs->fApplySIMDPadding) {
- convolveProcs->fApplySIMDPadding( output );
+ if (convolveProcs.fApplySIMDPadding) {
+ convolveProcs.fApplySIMDPadding( output );
}
}
ResizeMethod method,
int destWidth, int destHeight,
const SkIRect& destSubset,
- SkConvolutionProcs* convolveProcs,
+ const SkConvolutionProcs& convolveProcs,
SkBitmap::Allocator* allocator) {
// Ensure that the ResizeMethod enumeration is sound.
SkASSERT(((RESIZE_FIRST_QUALITY_METHOD <= method) &&
const SkBitmap& source,
ResizeMethod method,
int destWidth, int destHeight,
- SkConvolutionProcs* convolveProcs,
+ const SkConvolutionProcs& convolveProcs,
SkBitmap::Allocator* allocator) {
SkIRect destSubset = { 0, 0, destWidth, destHeight };
return Resize(resultPtr, source, method, destWidth, destHeight, destSubset,
ResizeMethod method,
int dest_width, int dest_height,
const SkIRect& dest_subset,
- SkConvolutionProcs *convolveProcs = NULL,
+ const SkConvolutionProcs&,
SkBitmap::Allocator* allocator = NULL);
// Alternate version for resizing and returning the entire bitmap rather than
const SkBitmap& source,
ResizeMethod method,
int dest_width, int dest_height,
- SkConvolutionProcs *convolveProcs = NULL,
+ const SkConvolutionProcs&,
SkBitmap::Allocator* allocator = NULL);
};
const SkConvolutionFilter1D& filterY,
int outputByteRowStride,
unsigned char* output,
- SkConvolutionProcs* convolveProcs,
+ const SkConvolutionProcs& convolveProcs,
bool useSimdIfPossible) {
int maxYFilterSize = filterY.maxFilter();
// convolution pass yet. Somehow Windows does not like it.
int rowBufferWidth = (filterX.numValues() + 15) & ~0xF;
int rowBufferHeight = maxYFilterSize +
- (convolveProcs->fConvolve4RowsHorizontally ? 4 : 0);
+ (convolveProcs.fConvolve4RowsHorizontally ? 4 : 0);
CircularRowBuffer rowBuffer(rowBufferWidth,
rowBufferHeight,
filterOffset);
// rows we need to avoid the SSE implementation for here.
filterX.FilterForValue(filterX.numValues() - 1, &lastFilterOffset,
&lastFilterLength);
- int avoidSimdRows = 1 + convolveProcs->fExtraHorizontalReads /
+ int avoidSimdRows = 1 + convolveProcs.fExtraHorizontalReads /
(lastFilterOffset + lastFilterLength);
filterY.FilterForValue(numOutputRows - 1, &lastFilterOffset,
// Generate output rows until we have enough to run the current filter.
while (nextXRow < filterOffset + filterLength) {
- if (convolveProcs->fConvolve4RowsHorizontally &&
+ if (convolveProcs.fConvolve4RowsHorizontally &&
nextXRow + 3 < lastFilterOffset + lastFilterLength -
avoidSimdRows) {
const unsigned char* src[4];
src[i] = &sourceData[(nextXRow + i) * sourceByteRowStride];
outRow[i] = rowBuffer.advanceRow();
}
- convolveProcs->fConvolve4RowsHorizontally(src, filterX, outRow);
+ convolveProcs.fConvolve4RowsHorizontally(src, filterX, outRow);
nextXRow += 4;
} else {
// Check if we need to avoid SSE2 for this row.
- if (convolveProcs->fConvolveHorizontally &&
+ if (convolveProcs.fConvolveHorizontally &&
nextXRow < lastFilterOffset + lastFilterLength -
avoidSimdRows) {
- convolveProcs->fConvolveHorizontally(
+ convolveProcs.fConvolveHorizontally(
&sourceData[nextXRow * sourceByteRowStride],
filterX, rowBuffer.advanceRow(), sourceHasAlpha);
} else {
unsigned char* const* firstRowForFilter =
&rowsToConvolve[filterOffset - firstRowInCircularBuffer];
- if (convolveProcs->fConvolveVertically) {
- convolveProcs->fConvolveVertically(filterValues, filterLength,
+ if (convolveProcs.fConvolveVertically) {
+ convolveProcs.fConvolveVertically(filterValues, filterLength,
firstRowForFilter,
filterX.numValues(), curOutputRow,
sourceHasAlpha);
const SkConvolutionFilter1D& yfilter,
int outputByteRowStride,
unsigned char* output,
- SkConvolutionProcs* convolveProcs,
+ const SkConvolutionProcs&,
bool useSimdIfPossible);
#endif // SK_CONVOLVER_H
}
}
-void SkBitmapProcState::platformConvolutionProcs() {
+void SkBitmapProcState::platformConvolutionProcs(SkConvolutionProcs* procs) {
if (sk_cpu_arm_has_neon()) {
- fConvolutionProcs->fExtraHorizontalReads = 3;
- fConvolutionProcs->fConvolveVertically = &convolveVertically_arm;
+ procs->fExtraHorizontalReads = 3;
+ procs->fConvolveVertically = &convolveVertically_arm;
// next line is commented out because the four-row convolution function above is
// just a no-op. Please see the comment above its definition, and the SSE implementation
// leaving it as NULL will just cause the convolution system to not attempt
// to operate on four rows at once, which is correct but not performance-optimal.
- // fConvolutionProcs->fConvolve4RowsHorizontally = &convolve4RowsHorizontally_arm;
+ // procs->fConvolve4RowsHorizontally = &convolve4RowsHorizontally_arm;
- fConvolutionProcs->fConvolve4RowsHorizontally = NULL;
+ procs->fConvolve4RowsHorizontally = NULL;
- fConvolutionProcs->fConvolveHorizontally = &convolveHorizontally_arm;
- fConvolutionProcs->fApplySIMDPadding = &applySIMDPadding_arm;
+ procs->fConvolveHorizontally = &convolveHorizontally_arm;
+ procs->fApplySIMDPadding = &applySIMDPadding_arm;
}
}
SK_CONF_DECLARE( bool, c_hqfilter_sse, "bitmap.filter.highQualitySSE", false, "Use SSE optimized version of high quality image filters");
-void SkBitmapProcState::platformConvolutionProcs() {
+void SkBitmapProcState::platformConvolutionProcs(SkConvolutionProcs* procs) {
if (cachedHasSSE2()) {
- fConvolutionProcs->fExtraHorizontalReads = 3;
- fConvolutionProcs->fConvolveVertically = &convolveVertically_SSE2;
- fConvolutionProcs->fConvolve4RowsHorizontally = &convolve4RowsHorizontally_SSE2;
- fConvolutionProcs->fConvolveHorizontally = &convolveHorizontally_SSE2;
- fConvolutionProcs->fApplySIMDPadding = &applySIMDPadding_SSE2;
+ procs->fExtraHorizontalReads = 3;
+ procs->fConvolveVertically = &convolveVertically_SSE2;
+ procs->fConvolve4RowsHorizontally = &convolve4RowsHorizontally_SSE2;
+ procs->fConvolveHorizontally = &convolveHorizontally_SSE2;
+ procs->fApplySIMDPadding = &applySIMDPadding_SSE2;
}
}