Attempt 3: SkRasterPipelineBlitter: support A8
authorMike Klein <mtklein@chromium.org>
Fri, 13 Jan 2017 12:59:23 +0000 (07:59 -0500)
committerMike Klein <mtklein@chromium.org>
Fri, 13 Jan 2017 13:25:28 +0000 (13:25 +0000)
Now that SkOpts_hsw.cpp no longer hooks in SkRasterPipeline_opts,
it should be safe to try this again.

This reverts commit 86d55b312a2649d80890ccf75f24571ada0265f1.

Change-Id: I2d495600ca9d3a0f49c2e02fbaaae349cefac3a1
Reviewed-on: https://skia-review.googlesource.com/6985
Reviewed-by: Mike Klein <mtklein@chromium.org>
bench/CoverageBench.cpp
src/core/SkBlitter.cpp
src/core/SkRasterPipeline.h
src/core/SkRasterPipelineBlitter.cpp
src/opts/SkNx_sse.h
src/opts/SkRasterPipeline_opts.h

index e1b53f8..ce590e5 100644 (file)
@@ -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());
index c97956c..86c49d0 100644 (file)
@@ -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);
index 887e535..949146c 100644 (file)
@@ -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)                                   \
index 9fad0b4..4d21b19 100644 (file)
@@ -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;
index 1ff72d1..5ef5eda 100644 (file)
@@ -659,6 +659,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
 
index 0d42b1f..41a10b9 100644 (file)
@@ -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);