aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/core/SkBitmapProcShader.cpp5
-rw-r--r--src/core/SkBlitter_RGB16.cpp6
-rw-r--r--src/core/SkShader.cpp2
-rw-r--r--src/effects/SkGradientShader.cpp125
4 files changed, 33 insertions, 105 deletions
diff --git a/src/core/SkBitmapProcShader.cpp b/src/core/SkBitmapProcShader.cpp
index cb4d129d5b..a8e21b4f5f 100644
--- a/src/core/SkBitmapProcShader.cpp
+++ b/src/core/SkBitmapProcShader.cpp
@@ -132,7 +132,10 @@ bool SkBitmapProcShader::setContext(const SkBitmap& device,
// if we're only 1-pixel heigh, and we don't rotate, then we can claim this
if (1 == fState.fBitmap->height() &&
only_scale_and_translate(this->getTotalInverse())) {
- flags |= kConstInY_Flag;
+ flags |= kConstInY32_Flag;
+ if (flags & kHasSpan16_Flag) {
+ flags |= kConstInY16_Flag;
+ }
}
fFlags = flags;
diff --git a/src/core/SkBlitter_RGB16.cpp b/src/core/SkBlitter_RGB16.cpp
index c41efef0a5..ac6b5d0bbf 100644
--- a/src/core/SkBlitter_RGB16.cpp
+++ b/src/core/SkBlitter_RGB16.cpp
@@ -528,7 +528,7 @@ void SkRGB16_Shader16_Blitter::blitRect(int x, int y, int width, int height) {
int alpha = shader->getSpan16Alpha();
if (0xFF == alpha) {
- if (fShaderFlags & SkShader::kConstInY_Flag) {
+ if (fShaderFlags & SkShader::kConstInY16_Flag) {
// have the shader blit directly into the device the first time
shader->shadeSpan16(x, y, dst, width);
// and now just memcpy that line on the subsequent lines
@@ -549,7 +549,7 @@ void SkRGB16_Shader16_Blitter::blitRect(int x, int y, int width, int height) {
} else {
int scale = SkAlpha255To256(alpha);
uint16_t* span16 = (uint16_t*)fBuffer;
- if (fShaderFlags & SkShader::kConstInY_Flag) {
+ if (fShaderFlags & SkShader::kConstInY16_Flag) {
shader->shadeSpan16(x, y, span16, width);
do {
SkBlendRGB16(span16, dst, scale, width);
@@ -668,7 +668,7 @@ void SkRGB16_Shader_Blitter::blitRect(int x, int y, int width, int height) {
uint16_t* dst = fDevice.getAddr16(x, y);
size_t dstRB = fDevice.rowBytes();
- if (fShaderFlags & SkShader::kConstInY_Flag) {
+ if (fShaderFlags & SkShader::kConstInY32_Flag) {
shader->shadeSpan(x, y, buffer, width);
do {
proc(dst, buffer, width, 0xFF, x, y);
diff --git a/src/core/SkShader.cpp b/src/core/SkShader.cpp
index 5567914530..5290f2ff0a 100644
--- a/src/core/SkShader.cpp
+++ b/src/core/SkShader.cpp
@@ -263,7 +263,7 @@ bool SkColorShader::setContext(const SkBitmap& device, const SkPaint& paint,
}
fPMColor = SkPackARGB32(a, r, g, b);
- fFlags = kHasSpan16_Flag | kConstInY_Flag;
+ fFlags = kHasSpan16_Flag | kConstInY32_Flag;
if (SkGetPackedA32(fPMColor) == 255) {
fFlags |= kOpaqueAlpha_Flag;
}
diff --git a/src/effects/SkGradientShader.cpp b/src/effects/SkGradientShader.cpp
index 635e0e579f..860e902dd2 100644
--- a/src/effects/SkGradientShader.cpp
+++ b/src/effects/SkGradientShader.cpp
@@ -20,18 +20,6 @@
#include "SkUnitMapper.h"
#include "SkUtils.h"
-/*
- ToDo
-
- - not sure we still need the full Rec struct, now that we're using a cache
- - detect const-alpha (but not opaque) in getFlags()
-*/
-
-/* dither seems to look better, but not stuningly yet, and it slows us down a little
- so its not on by default yet.
-*/
-#define TEST_GRADIENT_DITHER
-
///////////////////////////////////////////////////////////////////////////
typedef SkFixed (*TileProc)(SkFixed);
@@ -503,12 +491,9 @@ static inline U16CPU dot6to16(unsigned x) {
const uint16_t* Gradient_Shader::getCache16() {
if (fCache16 == NULL) {
- if (fCache16Storage == NULL) // set the storage and our working ptr
-#ifdef TEST_GRADIENT_DITHER
+ if (fCache16Storage == NULL) { // set the storage and our working ptr
fCache16Storage = (uint16_t*)sk_malloc_throw(sizeof(uint16_t) * kCache16Count * 2);
-#else
- fCache16Storage = (uint16_t*)sk_malloc_throw(sizeof(uint16_t) * kCache16Count);
-#endif
+ }
fCache16 = fCache16Storage;
if (fColorCount == 2) {
build_16bit_cache(fCache16, fOrigColors[0], fOrigColors[1], kCache16Count);
@@ -527,20 +512,14 @@ const uint16_t* Gradient_Shader::getCache16() {
}
if (fMapper) {
-#ifdef TEST_GRADIENT_DITHER
fCache16Storage = (uint16_t*)sk_malloc_throw(sizeof(uint16_t) * kCache16Count * 2);
-#else
- fCache16Storage = (uint16_t*)sk_malloc_throw(sizeof(uint16_t) * kCache16Count);
-#endif
uint16_t* linear = fCache16; // just computed linear data
uint16_t* mapped = fCache16Storage; // storage for mapped data
SkUnitMapper* map = fMapper;
for (int i = 0; i < 64; i++) {
int index = map->mapUnit16(dot6to16(i)) >> 10;
mapped[i] = linear[index];
-#ifdef TEST_GRADIENT_DITHER
mapped[i + 64] = linear[index + 64];
-#endif
}
sk_free(fCache16);
fCache16 = fCache16Storage;
@@ -655,7 +634,13 @@ bool Linear_Gradient::setContext(const SkBitmap& device, const SkPaint& paint,
unsigned mask = SkMatrix::kTranslate_Mask | SkMatrix::kScale_Mask;
if ((fDstToIndex.getType() & ~mask) == 0) {
- fFlags |= SkShader::kConstInY_Flag;
+ fFlags |= SkShader::kConstInY32_Flag;
+ if ((fFlags & SkShader::kHasSpan16_Flag) && !paint.isDither()) {
+ // only claim this if we do have a 16bit mode (i.e. none of our
+ // colors have alpha), and if we are not dithering (which obviously
+ // is not const in Y).
+ fFlags |= SkShader::kConstInY16_Flag;
+ }
}
return true;
}
@@ -779,11 +764,9 @@ bool Linear_Gradient::asABitmap(SkBitmap* bitmap, SkMatrix* matrix,
return true;
}
-#ifdef TEST_GRADIENT_DITHER
-static void dither_memset16(uint16_t dst[], uint16_t value, uint16_t other, int count)
-{
- if (reinterpret_cast<uintptr_t>(dst) & 2)
- {
+static void dither_memset16(uint16_t dst[], uint16_t value, uint16_t other,
+ int count) {
+ if (reinterpret_cast<uintptr_t>(dst) & 2) {
*dst++ = value;
count -= 1;
SkTSwap(value, other);
@@ -791,10 +774,10 @@ static void dither_memset16(uint16_t dst[], uint16_t value, uint16_t other, int
sk_memset32((uint32_t*)dst, (value << 16) | other, count >> 1);
- if (count & 1)
+ if (count & 1) {
dst[count - 1] = value;
+ }
}
-#endif
void Linear_Gradient::shadeSpan16(int x, int y, uint16_t dstC[], int count)
{
@@ -804,9 +787,7 @@ void Linear_Gradient::shadeSpan16(int x, int y, uint16_t dstC[], int count)
SkMatrix::MapXYProc dstProc = fDstToIndexProc;
TileProc proc = fTileProc;
const uint16_t* cache = this->getCache16();
-#ifdef TEST_GRADIENT_DITHER
int toggle = ((x ^ y) & 1) << kCache16Bits;
-#endif
if (fDstToIndexClass != kPerspective_MatrixClass) {
dstProc(fDstToIndex, SkIntToScalar(x), SkIntToScalar(y), &srcPt);
@@ -827,34 +808,22 @@ void Linear_Gradient::shadeSpan16(int x, int y, uint16_t dstC[], int count)
// we're a vertical gradient, so no change in a span
unsigned fi = proc(fx) >> 10;
SkASSERT(fi <= 63);
-#ifdef TEST_GRADIENT_DITHER
dither_memset16(dstC, cache[toggle + fi], cache[(toggle ^ (1 << kCache16Bits)) + fi], count);
-#else
- sk_memset16(dstC, cache[fi], count);
-#endif
} else if (proc == clamp_tileproc) {
do {
unsigned fi = SkClampMax(fx >> 10, 63);
SkASSERT(fi <= 63);
fx += dx;
-#ifdef TEST_GRADIENT_DITHER
*dstC++ = cache[toggle + fi];
toggle ^= (1 << kCache16Bits);
-#else
- *dstC++ = cache[fi];
-#endif
} while (--count != 0);
} else if (proc == mirror_tileproc) {
do {
unsigned fi = mirror_6bits(fx >> 10);
SkASSERT(fi <= 0x3F);
fx += dx;
-#ifdef TEST_GRADIENT_DITHER
*dstC++ = cache[toggle + fi];
toggle ^= (1 << kCache16Bits);
-#else
- *dstC++ = cache[fi];
-#endif
} while (--count != 0);
} else {
SkASSERT(proc == repeat_tileproc);
@@ -862,12 +831,8 @@ void Linear_Gradient::shadeSpan16(int x, int y, uint16_t dstC[], int count)
unsigned fi = repeat_6bits(fx >> 10);
SkASSERT(fi <= 0x3F);
fx += dx;
-#ifdef TEST_GRADIENT_DITHER
*dstC++ = cache[toggle + fi];
toggle ^= (1 << kCache16Bits);
-#else
- *dstC++ = cache[fi];
-#endif
} while (--count != 0);
}
} else {
@@ -879,12 +844,8 @@ void Linear_Gradient::shadeSpan16(int x, int y, uint16_t dstC[], int count)
SkASSERT(fi <= 0xFFFF);
int index = fi >> (16 - kCache16Bits);
-#ifdef TEST_GRADIENT_DITHER
*dstC++ = cache[toggle + index];
toggle ^= (1 << kCache16Bits);
-#else
- *dstC++ = cache[index];
-#endif
dstX += SK_Scalar1;
} while (--count != 0);
@@ -1033,40 +994,33 @@ public:
} while (--count != 0);
}
}
- virtual void shadeSpan16(int x, int y, uint16_t dstC[], int count)
- {
+
+ virtual void shadeSpan16(int x, int y, uint16_t dstC[], int count) {
SkASSERT(count > 0);
SkPoint srcPt;
SkMatrix::MapXYProc dstProc = fDstToIndexProc;
TileProc proc = fTileProc;
const uint16_t* cache = this->getCache16();
-#ifdef TEST_GRADIENT_DITHER
int toggle = ((x ^ y) & 1) << kCache16Bits;
-#endif
- if (fDstToIndexClass != kPerspective_MatrixClass)
- {
+ if (fDstToIndexClass != kPerspective_MatrixClass) {
dstProc(fDstToIndex, SkIntToScalar(x), SkIntToScalar(y), &srcPt);
SkFixed dx, fx = SkScalarToFixed(srcPt.fX);
SkFixed dy, fy = SkScalarToFixed(srcPt.fY);
- if (fDstToIndexClass == kFixedStepInX_MatrixClass)
- {
+ if (fDstToIndexClass == kFixedStepInX_MatrixClass) {
SkFixed storage[2];
(void)fDstToIndex.fixedStepInX(SkIntToScalar(y), &storage[0], &storage[1]);
dx = storage[0];
dy = storage[1];
- }
- else
- {
+ } else {
SkASSERT(fDstToIndexClass == kLinear_MatrixClass);
dx = SkScalarToFixed(fDstToIndex.getScaleX());
dy = SkScalarToFixed(fDstToIndex.getSkewY());
}
- if (proc == clamp_tileproc)
- {
+ if (proc == clamp_tileproc) {
const uint8_t* sqrt_table = gSqrt8Table;
/* knock these down so we can pin against +- 0x7FFF, which is an immediate load,
@@ -1079,8 +1033,7 @@ public:
dx >>= 1;
fy >>= 1;
dy >>= 1;
- if (dy == 0) // might perform this check for the other modes, but the win will be a smaller % of the total
- {
+ if (dy == 0) { // might perform this check for the other modes, but the win will be a smaller % of the total
fy = SkPin32(fy, -0xFFFF >> 1, 0xFFFF >> 1);
fy *= fy;
do {
@@ -1088,16 +1041,10 @@ public:
unsigned fi = (xx * xx + fy) >> (14 + 16 - kSQRT_TABLE_BITS);
fi = SkFastMin32(fi, 0xFFFF >> (16 - kSQRT_TABLE_BITS));
fx += dx;
-#ifdef TEST_GRADIENT_DITHER
*dstC++ = cache[toggle + (sqrt_table[fi] >> (8 - kCache16Bits))];
toggle ^= (1 << kCache16Bits);
-#else
- *dstC++ = cache[sqrt_table[fi] >> (8 - kCache16Bits)];
-#endif
} while (--count != 0);
- }
- else
- {
+ } else {
do {
unsigned xx = SkPin32(fx, -0xFFFF >> 1, 0xFFFF >> 1);
unsigned fi = SkPin32(fy, -0xFFFF >> 1, 0xFFFF >> 1);
@@ -1105,33 +1052,21 @@ public:
fi = SkFastMin32(fi, 0xFFFF >> (16 - kSQRT_TABLE_BITS));
fx += dx;
fy += dy;
-#ifdef TEST_GRADIENT_DITHER
*dstC++ = cache[toggle + (sqrt_table[fi] >> (8 - kCache16Bits))];
toggle ^= (1 << kCache16Bits);
-#else
- *dstC++ = cache[sqrt_table[fi] >> (8 - kCache16Bits)];
-#endif
} while (--count != 0);
}
- }
- else if (proc == mirror_tileproc)
- {
+ } else if (proc == mirror_tileproc) {
do {
SkFixed dist = SkFixedSqrt(SkFixedSquare(fx) + SkFixedSquare(fy));
unsigned fi = mirror_tileproc(dist);
SkASSERT(fi <= 0xFFFF);
fx += dx;
fy += dy;
-#ifdef TEST_GRADIENT_DITHER
*dstC++ = cache[toggle + (fi >> (16 - kCache16Bits))];
toggle ^= (1 << kCache16Bits);
-#else
- *dstC++ = cache[fi >> (16 - kCache16Bits)];
-#endif
} while (--count != 0);
- }
- else
- {
+ } else {
SkASSERT(proc == repeat_tileproc);
do {
SkFixed dist = SkFixedSqrt(SkFixedSquare(fx) + SkFixedSquare(fy));
@@ -1139,17 +1074,11 @@ public:
SkASSERT(fi <= 0xFFFF);
fx += dx;
fy += dy;
-#ifdef TEST_GRADIENT_DITHER
*dstC++ = cache[toggle + (fi >> (16 - kCache16Bits))];
toggle ^= (1 << kCache16Bits);
-#else
- *dstC++ = cache[fi >> (16 - kCache16Bits)];
-#endif
} while (--count != 0);
}
- }
- else // perspective case
- {
+ } else { // perspective case
SkScalar dstX = SkIntToScalar(x);
SkScalar dstY = SkIntToScalar(y);
do {
@@ -1158,12 +1087,8 @@ public:
SkASSERT(fi <= 0xFFFF);
int index = fi >> (16 - kCache16Bits);
-#ifdef TEST_GRADIENT_DITHER
*dstC++ = cache[toggle + index];
toggle ^= (1 << kCache16Bits);
-#else
- *dstC++ = cache[index];
-#endif
dstX += SK_Scalar1;
} while (--count != 0);