diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/core/SkBitmapProcState.h | 2 | ||||
-rw-r--r-- | src/opts/SkBitmapProcState_opts_arm.cpp | 140 |
2 files changed, 142 insertions, 0 deletions
diff --git a/src/core/SkBitmapProcState.h b/src/core/SkBitmapProcState.h index 1b42b61..90dbf35 100644 --- a/src/core/SkBitmapProcState.h +++ b/src/core/SkBitmapProcState.h @@ -146,5 +146,7 @@ void ClampX_ClampY_nofilter_affine(const SkBitmapProcState& s, uint32_t xy[], int count, int x, int y); void SI8_opaque_D32_filter_DX(const SkBitmapProcState& s, const uint32_t xy[], int count, SkPMColor colors[]); +void S32_opaque_D32_nofilter_DX(const SkBitmapProcState& s, const uint32_t xy[], + int count, SkPMColor colors[]); #endif diff --git a/src/opts/SkBitmapProcState_opts_arm.cpp b/src/opts/SkBitmapProcState_opts_arm.cpp index ce75fea..3a5694f 100644 --- a/src/opts/SkBitmapProcState_opts_arm.cpp +++ b/src/opts/SkBitmapProcState_opts_arm.cpp @@ -776,6 +776,144 @@ void Repeat_SI8_opaque_D32_filter_DX_shaderproc(const SkBitmapProcState& s, int s.fBitmap->getColorTable()->unlockColors(false); } + + +void Clamp_S32_opaque_D32_nofilter_DX_shaderproc(const SkBitmapProcState& s, int x, int y, + SkPMColor* SK_RESTRICT colors, int count) { + SkASSERT((s.fInvType & ~(SkMatrix::kTranslate_Mask | + SkMatrix::kScale_Mask)) == 0); + SkASSERT(s.fInvKy == 0); + SkASSERT(count > 0 && colors != NULL); + SkASSERT(!s.fDoFilter); + SkDEBUGCODE(SkASSERT(s.fBitmap->config() == SkBitmap::kARGB_8888_Config); SkASSERT(s.fAlphaScale == 256);) + + const register unsigned maxX = s.fBitmap->width() - 1; + const SkFixed dx = s.fInvSx; + register SkFixed fx; + const SkPMColor* SK_RESTRICT row; + int num; + + { + SkPoint pt; + s.fInvProc(*s.fInvMatrix, SkIntToScalar(x) + SK_ScalarHalf, + SkIntToScalar(y) + SK_ScalarHalf, &pt); + SkFixed fy = SkScalarToFixed(pt.fY); + const unsigned maxY = s.fBitmap->height() - 1; + int yy = SkClampMax(SkFixedFloorToInt(fy), maxY); + const char* SK_RESTRICT srcAddr = (const char*)s.fBitmap->getPixels(); + unsigned rb = s.fBitmap->rowBytes(); + row = (const SkPMColor*)(srcAddr + yy * rb); + // now initialize fx + fx = SkScalarToFixed(pt.fX); + } + + // Single pixel left in source? + if (maxX == 0) { + sk_memset32(colors, row[0], count); + return; + } + + // Special case if unscaled. + if (dx == SK_Fixed1) { + fx = SkFixedFloorToInt(fx); + + // Any clamped pixels at the beginning? + if (fx < 0) { + num = SkMin32(-fx, count); + sk_memset32(colors, row[0], num); + count -= num; + fx += num; + colors += num; + } + + // Copy pixels + num = SkMin32(SkMax32(maxX + 1 - fx, 0), count); + memcpy(colors, row + fx, num * sizeof(SkPMColor)); + count -= num; + + if (count > 0) { + colors += num; + sk_memset32(colors, row[maxX], count); + } + + return; + } + + // Can we run unclamped case? + if (((dx >= 0) && (((fx + (count - 1) * dx) >> 16) <= (const signed)maxX) && (fx >= 0)) || + ((dx < 0) && ((fx >> 16) <= (const signed)maxX) && (((fx + (count - 1) * dx) >> 16) >= 0))) { + + asm volatile ( + // Setup constants + "pld [%[row]] \n\t" // Pre-load source + "subs %[count], #4 \n\t" // Decrease loop counter + "bmi 2f \n\t" // + "pld [%[row], #32] \n\t" // Pre-load source + "1: \n\t" // Loop start + // Load pixels + "lsr r1, %[fx], #16 \n\t" // Calculate SkFixedFloorToInt(fx) + "add %[fx], %[fx], %[dx] \n\t" // Increment to next position + "add r1, %[row], r1, lsl #2 \n\t" // Calculate row[SkFixedFloorToInt(fx)]; + "vldr.32 s0, [r1] \n\t" // Load pixel #1 + + "lsr r2, %[fx], #16 \n\t" // Calculate SkFixedFloorToInt(fx) + "add %[fx], %[fx], %[dx] \n\t" // Increment to next position + "add r2, %[row], r2, lsl #2 \n\t" // Calculate row[SkFixedFloorToInt(fx)]; + "vldr.32 s1, [r2] \n\t" // Load pixel #2 + + "lsr r1, %[fx], #16 \n\t" // Calculate SkFixedFloorToInt(fx) + "add %[fx], %[fx], %[dx] \n\t" // Increment to next position + "add r1, %[row], r1, lsl #2 \n\t" // Calculate row[SkFixedFloorToInt(fx)]; + "vldr.32 s2, [r1] \n\t" // Load pixel #3 + + "lsr r2, %[fx], #16 \n\t" // Calculate SkFixedFloorToInt(fx) + "add r2, %[row], r2, lsl #2 \n\t" // Calculate row[SkFixedFloorToInt(fx)]; + "vldr.32 s3, [r2] \n\t" // Load pixel #4 + // Write pixels + "subs %[count], #4 \n\t" // Decrease loop counter + "pld [r2, #52] \n\t" // Pre-load source + "add %[fx], %[fx], %[dx] \n\t" // Increment to next position + "vstm %[colors]!, {s0-s3} \n\t" // Write result to memory + + "bpl 1b \n\t" + "2: \n\t" // Loop start + "add %[count], #4 \n\t" // Restore loop counter + : [fx] "+r" (fx), [colors] "+r" (colors), [count] "+r" (count) + : [row] "r" (row), [dx] "r" (dx) + : "cc", "memory", "r1", "r2", "s0", "s1", "s2", "s3" + ); + + for (num = (count & 3); num > 0; --num) { + *colors++ = row[SkFixedFloorToInt(fx)]; + fx += dx; + } + + return; + } + + // Fallback case + for (num = (count >> 2); num > 0; --num) { + SkPMColor p0, p1, p2, p3; + + p0 = row[SkClampMax(SkFixedFloorToInt(fx), maxX)]; + fx += dx; + p1 = row[SkClampMax(SkFixedFloorToInt(fx), maxX)]; + fx += dx; + p2 = row[SkClampMax(SkFixedFloorToInt(fx), maxX)]; + fx += dx; + p3 = row[SkClampMax(SkFixedFloorToInt(fx), maxX)]; + *colors++ = p0; + *colors++ = p1; + *colors++ = p2; + *colors++ = p3; + fx += dx; + } + + for (num = (count & 3); num > 0; --num) { + *colors++ = row[SkClampMax(SkFixedFloorToInt(fx), maxX)]; + fx += dx; + } +} #endif @@ -821,6 +959,8 @@ void SkBitmapProcState::platformProcs() { #if defined(__ARM_HAVE_NEON) && defined(SK_CPU_LENDIAN) if (S32_opaque_D32_filter_DX == fSampleProc32 && clamp_clamp) { fShaderProc32 = Clamp_S32_opaque_D32_filter_DX_shaderproc; + } else if (S32_opaque_D32_nofilter_DX == fSampleProc32 && clamp_clamp) { + fShaderProc32 = Clamp_S32_opaque_D32_nofilter_DX_shaderproc; } #endif break; |