aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Mike Klein <mtklein@chromium.org>2017-01-06 11:30:55 -0500
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2017-01-06 17:32:03 +0000
commitf55ea6a1deb21120944d406124a2984b5009260a (patch)
tree7601c3e25a5ec9a35a59ea2cc8abec44095422da
parentc4bb2b9721adc8ef2453dcf5e20e8e6dfaf7be64 (diff)
Retry "SkRasterPipelineBlitter: support A8"...
...preferring SkA8_Coverage_Blitter over SkRasterPipelineBlitter. I think we could make this work with SkRasterPipelineBlitter (tell it, draw white in Src mode with this mask), but the existing blitter is pretty hard to beat in efficiency and correctness. CQ_INCLUDE_TRYBOTS=skia.primary:Perf-Ubuntu-Clang-GCE-CPU-AVX2-x86_64-Debug-MSAN,Test-Ubuntu-GCC-GCE-CPU-AVX2-x86_64-Release-SKNX_NO_SIMD Change-Id: I72df9995c63f3334d8111c59711818cb5ed1e63c Reviewed-on: https://skia-review.googlesource.com/6627 Reviewed-by: Mike Klein <mtklein@chromium.org> Commit-Queue: Mike Klein <mtklein@chromium.org>
-rw-r--r--bench/CoverageBench.cpp5
-rw-r--r--src/core/SkBlitter.cpp13
-rw-r--r--src/core/SkRasterPipeline.h1
-rw-r--r--src/core/SkRasterPipelineBlitter.cpp5
-rw-r--r--src/opts/SkNx_sse.h4
-rw-r--r--src/opts/SkRasterPipeline_opts.h10
6 files changed, 32 insertions, 6 deletions
diff --git a/bench/CoverageBench.cpp b/bench/CoverageBench.cpp
index e1b53f879d..ce590e5c49 100644
--- a/bench/CoverageBench.cpp
+++ b/bench/CoverageBench.cpp
@@ -34,6 +34,11 @@ public:
fPath.quadTo(250, 0, 0, 500);
fPixmap.alloc(SkImageInfo::MakeA8(500, 500));
+ if (!drawCoverage) {
+ // drawPathCoverage() goes out of its way to work fine with an uninitialized
+ // dst buffer, even in "SrcOver" mode, but ordinary drawing sure doesn't.
+ fPixmap.erase(0);
+ }
fIdentity.setIdentity();
fRC.setRect(fPath.getBounds().round());
diff --git a/src/core/SkBlitter.cpp b/src/core/SkBlitter.cpp
index c97956c20f..86c49d08ae 100644
--- a/src/core/SkBlitter.cpp
+++ b/src/core/SkBlitter.cpp
@@ -857,6 +857,12 @@ SkBlitter* SkBlitter::Choose(const SkPixmap& device,
p->setColor(0);
}
+ if (kAlpha_8_SkColorType == device.colorType() && drawCoverage) {
+ SkASSERT(nullptr == shader);
+ SkASSERT(paint->isSrcOver());
+ return allocator->createT<SkA8_Coverage_Blitter>(device, *paint);
+ }
+
if (SkBlitter* blitter = SkCreateRasterPipelineBlitter(device, *paint, matrix, allocator)) {
return blitter;
}
@@ -913,11 +919,8 @@ SkBlitter* SkBlitter::Choose(const SkPixmap& device,
SkBlitter* blitter = nullptr;
switch (device.colorType()) {
case kAlpha_8_SkColorType:
- if (drawCoverage) {
- SkASSERT(nullptr == shader);
- SkASSERT(paint->isSrcOver());
- blitter = allocator->createT<SkA8_Coverage_Blitter>(device, *paint);
- } else if (shader) {
+ SkASSERT(!drawCoverage); // Handled above.
+ if (shader) {
blitter = allocator->createT<SkA8_Shader_Blitter>(device, *paint, shaderContext);
} else {
blitter = allocator->createT<SkA8_Blitter>(device, *paint);
diff --git a/src/core/SkRasterPipeline.h b/src/core/SkRasterPipeline.h
index 61a44eb1db..e6c99159fa 100644
--- a/src/core/SkRasterPipeline.h
+++ b/src/core/SkRasterPipeline.h
@@ -65,6 +65,7 @@
M(from_srgb) M(to_srgb) \
M(from_2dot2) M(to_2dot2) \
M(constant_color) M(store_f32) \
+ M(load_a8) M(store_a8) \
M(load_565) M(store_565) \
M(load_f16) M(store_f16) \
M(load_8888) M(store_8888) \
diff --git a/src/core/SkRasterPipelineBlitter.cpp b/src/core/SkRasterPipelineBlitter.cpp
index 9fad0b4752..4d21b19bf0 100644
--- a/src/core/SkRasterPipelineBlitter.cpp
+++ b/src/core/SkRasterPipelineBlitter.cpp
@@ -79,9 +79,10 @@ SkBlitter* SkCreateRasterPipelineBlitter(const SkPixmap& dst,
static bool supported(const SkImageInfo& info) {
switch (info.colorType()) {
+ case kAlpha_8_SkColorType: return true;
+ case kRGB_565_SkColorType: return true;
case kN32_SkColorType: return info.gammaCloseToSRGB();
case kRGBA_F16_SkColorType: return true;
- case kRGB_565_SkColorType: return true;
default: return false;
}
}
@@ -188,6 +189,7 @@ void SkRasterPipelineBlitter::append_load_d(SkRasterPipeline* p) const {
p->append(SkRasterPipeline::move_src_dst);
switch (fDst.info().colorType()) {
+ case kAlpha_8_SkColorType: p->append(SkRasterPipeline::load_a8, &fDstPtr); break;
case kRGB_565_SkColorType: p->append(SkRasterPipeline::load_565, &fDstPtr); break;
case kBGRA_8888_SkColorType:
case kRGBA_8888_SkColorType: p->append(SkRasterPipeline::load_8888, &fDstPtr); break;
@@ -213,6 +215,7 @@ void SkRasterPipelineBlitter::append_store(SkRasterPipeline* p) const {
SkASSERT(supported(fDst.info()));
switch (fDst.info().colorType()) {
+ case kAlpha_8_SkColorType: p->append(SkRasterPipeline::store_a8, &fDstPtr); break;
case kRGB_565_SkColorType: p->append(SkRasterPipeline::store_565, &fDstPtr); break;
case kBGRA_8888_SkColorType:
case kRGBA_8888_SkColorType: p->append(SkRasterPipeline::store_8888, &fDstPtr); break;
diff --git a/src/opts/SkNx_sse.h b/src/opts/SkNx_sse.h
index 394115626e..d52509a03e 100644
--- a/src/opts/SkNx_sse.h
+++ b/src/opts/SkNx_sse.h
@@ -650,6 +650,10 @@ public:
hi = _mm256_extractf128_si256(src.fVec, 1);
return _mm_packus_epi32(lo, hi);
}
+ template<> AI /*static*/ Sk8b SkNx_cast<uint8_t>(const Sk8i& src) {
+ auto _16 = SkNx_cast<uint16_t>(src);
+ return _mm_packus_epi16(_16.fVec, _16.fVec);
+ }
#endif
diff --git a/src/opts/SkRasterPipeline_opts.h b/src/opts/SkRasterPipeline_opts.h
index 143a9ece79..3fe43e9838 100644
--- a/src/opts/SkRasterPipeline_opts.h
+++ b/src/opts/SkRasterPipeline_opts.h
@@ -497,6 +497,16 @@ STAGE_CTX(lerp_565, const uint16_t**) {
a = 1.0f;
}
+STAGE_CTX(load_a8, const uint8_t**) {
+ auto ptr = *ctx + x;
+ r = g = b = 0.0f;
+ a = SkNf_from_byte(load(tail, ptr));
+}
+STAGE_CTX(store_a8, uint8_t**) {
+ auto ptr = *ctx + x;
+ store(tail, SkNx_cast<uint8_t>(SkNf_round(255.0f, a)), ptr);
+}
+
STAGE_CTX(load_565, const uint16_t**) {
auto ptr = *ctx + x;
from_565(load(tail, ptr), &r,&g,&b);