Add a blend-wrong mode to SkRasterPipelineBlitter.
authorMike Klein <mtklein@chromium.org>
Tue, 7 Feb 2017 16:57:27 +0000 (11:57 -0500)
committerSkia Commit-Bot <skia-commit-bot@chromium.org>
Wed, 8 Feb 2017 15:38:49 +0000 (15:38 +0000)
This keeps correct linear blending as the only option exericsed,
but it should be easy to see how to turn on blend-wrong mode.

Change-Id: I7d87ef8ed00e8990107bd36b826f8d229d930400
Reviewed-on: https://skia-review.googlesource.com/8125
Reviewed-by: Brian Osman <brianosman@google.com>
Reviewed-by: Matt Sarett <msarett@google.com>
Commit-Queue: Mike Klein <mtklein@chromium.org>

src/core/SkBlitter.cpp
src/core/SkCoreBlitters.h
src/core/SkRasterPipelineBlitter.cpp

index a386904..ec519bd 100644 (file)
@@ -847,7 +847,7 @@ SkBlitter* SkBlitter::Choose(const SkPixmap& device,
         return alloc->make<SkA8_Coverage_Blitter>(device, *paint);
     }
 
-    if (SkBlitter* blitter = SkCreateRasterPipelineBlitter(device, *paint, matrix, alloc)) {
+    if (SkBlitter* blitter = SkCreateRasterPipelineBlitter(device, *paint, matrix, alloc, true)) {
         return blitter;
     }
 
index 63ddda9..42366cc 100644 (file)
@@ -205,6 +205,6 @@ SkBlitter* SkBlitter_ChooseD565(const SkPixmap& device, const SkPaint& paint,
 
 // Returns nullptr if no SkRasterPipeline blitter can be constructed for this paint.
 SkBlitter* SkCreateRasterPipelineBlitter(const SkPixmap&, const SkPaint&, const SkMatrix& ctm,
-                                         SkArenaAlloc*);
+                                         SkArenaAlloc*, bool blendCorrectly);
 
 #endif
index 1a00009..80e6344 100644 (file)
 class SkRasterPipelineBlitter : public SkBlitter {
 public:
     static SkBlitter* Create(const SkPixmap&, const SkPaint&, const SkMatrix& ctm,
-                             SkArenaAlloc*);
+                             SkArenaAlloc*, bool blendCorrectly);
 
-    SkRasterPipelineBlitter(SkPixmap dst, SkBlendMode blend, SkPM4f paintColor)
+    SkRasterPipelineBlitter(SkPixmap dst, SkBlendMode blend, SkPM4f paintColor, bool blendCorrectly)
         : fDst(dst)
         , fBlend(blend)
         , fPaintColor(paintColor)
+        , fBlendCorrectly(blendCorrectly)
     {}
 
     void blitH    (int x, int y, int w)                            override;
@@ -47,6 +48,7 @@ private:
     SkBlendMode      fBlend;
     SkPM4f           fPaintColor;
     SkRasterPipeline fShader;
+    bool             fBlendCorrectly;
 
     // These functions are compiled lazily when first used.
     std::function<void(size_t, size_t)> fBlitH         = nullptr,
@@ -71,8 +73,9 @@ private:
 SkBlitter* SkCreateRasterPipelineBlitter(const SkPixmap& dst,
                                          const SkPaint& paint,
                                          const SkMatrix& ctm,
-                                         SkArenaAlloc* alloc) {
-    return SkRasterPipelineBlitter::Create(dst, paint, ctm, alloc);
+                                         SkArenaAlloc* alloc,
+                                         bool blendCorrectly) {
+    return SkRasterPipelineBlitter::Create(dst, paint, ctm, alloc, blendCorrectly);
 }
 
 static bool supported(const SkImageInfo& info) {
@@ -88,11 +91,13 @@ static bool supported(const SkImageInfo& info) {
 SkBlitter* SkRasterPipelineBlitter::Create(const SkPixmap& dst,
                                            const SkPaint& paint,
                                            const SkMatrix& ctm,
-                                           SkArenaAlloc* alloc) {
+                                           SkArenaAlloc* alloc,
+                                           bool blendCorrectly) {
     auto blitter = alloc->make<SkRasterPipelineBlitter>(
             dst,
             paint.getBlendMode(),
-            SkPM4f_from_SkColor(paint.getColor(), dst.colorSpace()));
+            SkPM4f_from_SkColor(paint.getColor(), dst.colorSpace()),
+            blendCorrectly);
 
 
     SkBlendMode*      blend       = &blitter->fBlend;
@@ -126,6 +131,11 @@ SkBlitter* SkRasterPipelineBlitter::Create(const SkPixmap& dst,
         pipeline->append(SkRasterPipeline::constant_color, paintColor);
     }
 
+    // Some people want the rest of the pipeline to operate on sRGB encoded color channels...
+    if (!blendCorrectly && dst.info().gammaCloseToSRGB()) {
+        pipeline->append(SkRasterPipeline::to_srgb);
+    }
+
     if (colorFilter) {
         if (!colorFilter->appendStages(pipeline, dst.colorSpace(), &blitter->fArena,
                                        is_opaque)) {
@@ -201,7 +211,7 @@ void SkRasterPipelineBlitter::append_load_d(SkRasterPipeline* p) const {
 }
 
 void SkRasterPipelineBlitter::append_store(SkRasterPipeline* p) const {
-    if (fDst.info().gammaCloseToSRGB()) {
+    if (fBlendCorrectly && fDst.info().gammaCloseToSRGB()) {
         p->append(SkRasterPipeline::to_srgb);
     }
     if (fDst.info().colorType() == kBGRA_8888_SkColorType) {