Revert "Delete copyTo(Allocator), hide copyTo() behind flag"
authorMatt Sarett <msarett@google.com>
Thu, 27 Apr 2017 20:08:39 +0000 (20:08 +0000)
committerSkia Commit-Bot <skia-commit-bot@chromium.org>
Thu, 27 Apr 2017 20:08:45 +0000 (20:08 +0000)
This reverts commit d4a338f4d0a0cdc08d7d3668931c60997f0fa971.

Reason for revert: Looks like I missed something I was supposed to delete in Android.

Original change's description:
> Delete copyTo(Allocator), hide copyTo() behind flag
>
> Replace uses of copyTo() in Skia.
>
> Bug: skia:6464
> Change-Id: I921dc53a1c29a5176d18f05741f7c0b5a008e548
> Reviewed-on: https://skia-review.googlesource.com/14502
> Commit-Queue: Matt Sarett <msarett@google.com>
> Reviewed-by: Mike Reed <reed@google.com>
>

TBR=msarett@google.com,reed@google.com
NOPRESUBMIT=true
NOTREECHECKS=true
NOTRY=true

Change-Id: I4d252940cc6a2462b030007055ea6c229471fc6e
Reviewed-on: https://skia-review.googlesource.com/14602
Reviewed-by: Matt Sarett <msarett@google.com>
Commit-Queue: Matt Sarett <msarett@google.com>

30 files changed:
dm/DM.cpp
gm/all_bitmap_configs.cpp
gm/animatedGif.cpp
gm/bitmapcopy.cpp
gm/bitmapfilters.cpp
gm/copyTo4444.cpp
gm/showmiplevels.cpp
gm/simpleaaclip.cpp
include/core/SkBitmap.h
include/core/SkPixelRef.h
public.bzl
samplecode/SampleDither.cpp
samplecode/SampleDitherBitmap.cpp
samplecode/SampleFilter.cpp
src/core/SkBitmap.cpp
src/core/SkPixelRef.cpp
src/core/SkSpecialImage.cpp
src/pdf/SkPDFBitmap.cpp
src/ports/SkImageEncoder_CG.cpp
src/ports/SkImageEncoder_WIC.cpp
src/utils/mac/SkCreateCGImageRef.cpp
tests/BitmapCopyTest.cpp
tests/BitmapTest.cpp
tests/CodecAnimTest.cpp
tests/CodecTest.cpp
tools/debugger/SkDrawCommand.cpp
tools/picture_utils.cpp
tools/sk_tool_utils.cpp
tools/sk_tool_utils.h
tools/skdiff/skdiff_utils.cpp

index 6c8daf9..707c4c9 100644 (file)
--- a/dm/DM.cpp
+++ b/dm/DM.cpp
@@ -1123,8 +1123,7 @@ struct Task {
                         // We might consider promoting 565 to RGBA too.
                         if (bitmap.colorType() == kBGRA_8888_SkColorType) {
                             SkBitmap swizzle;
-                            SkAssertResult(sk_tool_utils::copy_to(&swizzle, kRGBA_8888_SkColorType,
-                                                                  bitmap));
+                            SkAssertResult(bitmap.copyTo(&swizzle, kRGBA_8888_SkColorType));
                             hash.write(swizzle.getPixels(), swizzle.getSize());
                         } else {
                             hash.write(bitmap.getPixels(), bitmap.getSize());
index 98d6621..7e9dfab 100644 (file)
 #include "SkColorPriv.h"
 
 static SkBitmap copy_bitmap(const SkBitmap& src, SkColorType colorType) {
-    const SkBitmap* srcPtr = &src;
-    SkBitmap tmp(src);
-    if (kRGB_565_SkColorType == colorType) {
-        tmp.setAlphaType(kOpaque_SkAlphaType);
-        srcPtr = &tmp;
-    }
-
     SkBitmap copy;
-    sk_tool_utils::copy_to(&copy, colorType, *srcPtr);
+    src.copyTo(&copy, colorType);
     copy.setImmutable();
     return copy;
 }
@@ -207,7 +200,7 @@ sk_sp<SkImage> make_not_native32_color_wheel() {
         const SkColorType ct = kBGRA_8888_SkColorType;
     #endif
     static_assert(ct != kN32_SkColorType, "BRGA!=RGBA");
-    SkAssertResult(sk_tool_utils::copy_to(&notN32bitmap, ct, n32bitmap));
+    SkAssertResult(n32bitmap.copyTo(&notN32bitmap, ct));
     SkASSERT(notN32bitmap.colorType() == ct);
     return SkImage::MakeFromBitmap(notN32bitmap);
 }
index dd08abf..c7871e0 100644 (file)
@@ -6,7 +6,6 @@
  */
 
 #include "gm.h"
-#include "sk_tool_utils.h"
 #include "SkAnimTimer.h"
 #include "SkCanvas.h"
 #include "SkCodec.h"
@@ -60,8 +59,7 @@ private:
                          && static_cast<size_t>(requiredFrame) < fFrames.size());
                 SkBitmap& requiredBitmap = fFrames[requiredFrame];
                 // For simplicity, do not try to cache old frames
-                if (requiredBitmap.getPixels() &&
-                        sk_tool_utils::copy_to(&bm, requiredBitmap.colorType(), requiredBitmap)) {
+                if (requiredBitmap.getPixels() && requiredBitmap.copyTo(&bm)) {
                     opts.fHasPriorFrame = true;
                 }
             }
index 7428c20..60eecf2 100644 (file)
@@ -71,7 +71,7 @@ protected:
         draw_checks(&canvasTmp, 40, 40);
 
         for (unsigned i = 0; i < NUM_CONFIGS; ++i) {
-            sk_tool_utils::copy_to(&fDst[i], gColorTypes[i], src);
+            src.copyTo(&fDst[i], gColorTypes[i]);
         }
 
         canvas->clear(sk_tool_utils::color_to_565(0xFFDDDDDD));
index 7dc9692..22e5d09 100644 (file)
@@ -68,9 +68,9 @@ static SkScalar draw_row(SkCanvas* canvas, const SkBitmap& bm) {
 class FilterGM : public skiagm::GM {
     void onOnceBeforeDraw() override {
         make_bm(&fBM8);
-        sk_tool_utils::copy_to(&fBM4444, kARGB_4444_SkColorType, fBM8);
-        sk_tool_utils::copy_to(&fBM16, kRGB_565_SkColorType, fBM8);
-        sk_tool_utils::copy_to(&fBM32, kN32_SkColorType, fBM8);
+        fBM8.copyTo(&fBM4444, kARGB_4444_SkColorType);
+        fBM8.copyTo(&fBM16, kRGB_565_SkColorType);
+        fBM8.copyTo(&fBM32, kN32_SkColorType);
     }
 
 public:
index f593a19..64f2c60 100644 (file)
@@ -6,7 +6,6 @@
  */
 
 #include "gm.h"
-#include "sk_tool_utils.h"
 
 #include "Resources.h"
 #include "SkCanvas.h"
@@ -38,7 +37,7 @@ protected:
             return;
         }
         canvas->drawBitmap(bm, 0, 0);
-        SkAssertResult(sk_tool_utils::copy_to(&bm4444, kARGB_4444_SkColorType, bm));
+        SkAssertResult(bm.copyTo(&bm4444, kARGB_4444_SkColorType));
         canvas->drawBitmap(bm4444, SkIntToScalar(bm.width()), 0);
     }
 
index 3e2091f..e5374e4 100644 (file)
@@ -120,7 +120,7 @@ protected:
 
     static void DrawAndFrame(SkCanvas* canvas, const SkBitmap& orig, SkScalar x, SkScalar y) {
         SkBitmap bm;
-        sk_tool_utils::copy_to(&bm, orig.colorType(), orig);
+        orig.copyTo(&bm);
         apply_gamma(bm);
 
         canvas->drawBitmap(bm, x, y, nullptr);
@@ -218,14 +218,7 @@ void copy_to(SkBitmap* dst, SkColorType dstColorType, const SkBitmap& src) {
         return sk_tool_utils::copy_to_g8(dst, src);
     }
 
-    const SkBitmap* srcPtr = &src;
-    SkBitmap tmp(src);
-    if (kRGB_565_SkColorType == dstColorType) {
-        tmp.setAlphaType(kOpaque_SkAlphaType);
-        srcPtr = &tmp;
-    }
-
-    sk_tool_utils::copy_to(dst, dstColorType, *srcPtr);
+    src.copyTo(dst, dstColorType);
 }
 
 /**
index 4c7407d..8f6c5c9 100644 (file)
@@ -27,7 +27,7 @@ static void paint_rgn(SkCanvas* canvas, const SkAAClip& clip,
     // need to copy for deferred drawing test to work
     SkBitmap bm2;
 
-    sk_tool_utils::copy_to(&bm2, bm.colorType(), bm);
+    bm.deepCopyTo(&bm2);
 
     canvas->drawBitmap(bm2,
                        SK_Scalar1 * mask.fBounds.fLeft,
index d38898c..8818829 100644 (file)
@@ -552,15 +552,39 @@ public:
     */
     bool extractSubset(SkBitmap* dst, const SkIRect& subset) const;
 
-#ifdef SK_SUPPORT_LEGACY_BITMAP_COPYTO
+#ifdef SK_BUILD_FOR_ANDROID
+    /** Makes a deep copy of this bitmap, respecting the requested colorType,
+     *  and allocating the dst pixels on the cpu.
+     *  Returns false if either there is an error (i.e. the src does not have
+     *  pixels) or the request cannot be satisfied (e.g. the src has per-pixel
+     *  alpha, and the requested colortype does not support alpha).
+     *  @param dst The bitmap to be sized and allocated
+     *  @param ct The desired colorType for dst
+     *  @param allocator Allocator used to allocate the pixelref for the dst
+     *                   bitmap. If this is null, the standard HeapAllocator
+     *                   will be used.
+     *  @return true if the copy was made.
+     */
+    bool copyTo(SkBitmap* dst, SkColorType ct, Allocator*) const;
+
+    bool copyTo(SkBitmap* dst, Allocator* allocator) const {
+        return this->copyTo(dst, this->colorType(), allocator);
+    }
+#endif
+
+    /** Makes a deep copy of this bitmap, respecting the requested colorType.
+     *  Returns false if either there is an error (i.e. the src does not have
+     *  pixels) or the request cannot be satisfied (e.g. the src has per-pixel
+     *  alpha, and the requested colortype does not support alpha).
+     *  @param dst The bitmap to be sized and allocated
+     *  @param ct The desired colorType for dst
+     *  @return true if the copy was made.
+     */
     bool copyTo(SkBitmap* dst, SkColorType ct) const;
+
     bool copyTo(SkBitmap* dst) const {
         return this->copyTo(dst, this->colorType());
     }
-    bool deepCopyTo(SkBitmap* dst) const {
-        return this->copyTo(dst, this->colorType());
-    }
-#endif
 
     /**
      *  Copy the bitmap's pixels into the specified buffer (pixels + rowBytes),
@@ -601,6 +625,20 @@ public:
         return this->writePixels(src, 0, 0);
     }
 
+    /**
+     *  Returns true if this bitmap's pixels can be converted into the requested
+     *  colorType, such that copyTo() could succeed.
+     */
+    bool canCopyTo(SkColorType colorType) const;
+
+    /** Makes a deep copy of this bitmap, keeping the copied pixels
+     *  in the same domain as the source: If the src pixels are allocated for
+     *  the cpu, then so will the dst. If the src pixels are allocated on the
+     *  gpu (typically as a texture), the it will do the same for the dst.
+     *  If the request cannot be fulfilled, returns false and dst is unmodified.
+     */
+    bool deepCopyTo(SkBitmap* dst) const;
+
 #ifdef SK_BUILD_FOR_ANDROID
     bool hasHardwareMipMap() const {
         return (fFlags & kHasHardwareMipMap_Flag) != 0;
@@ -698,8 +736,7 @@ private:
     uint8_t             fFlags;
 
     bool writePixels(const SkPixmap& src, int x, int y, SkTransferFunctionBehavior behavior);
-
-    bool canCopyTo(SkColorType colorType) const;
+    bool internalCopyTo(SkBitmap* dst, SkColorType ct, Allocator*) const;
 
     /*  Unreference any pixelrefs or colortables
     */
index 6a86e59..342863f 100644 (file)
@@ -165,6 +165,11 @@ private:
     friend class SkImage_Raster;
     friend class SkSpecialImage_Raster;
 
+    // When copying a bitmap to another with the same shape and config, we can safely
+    // clone the pixelref generation ID too, which makes them equivalent under caching.
+    friend class SkBitmap;  // only for cloneGenID
+    void cloneGenID(const SkPixelRef&);
+
     void setImmutableWithID(uint32_t genID);
     friend class SkImage_Gpu;
     friend class SkImage_Lazy;
index 9c41cdb..01d70f7 100644 (file)
@@ -648,7 +648,6 @@ DEFINES_IOS = [
 ]
 
 DEFINES_ALL = [
-    "SK_SUPPORT_LEGACY_BITMAP_COPYTO",
     # Chrome DEFINES.
     "SK_USE_FLOATBITS",
     "SK_USE_FREETYPE_EMBOLDEN",
index 6d91fda..76ebecc 100644 (file)
@@ -19,7 +19,6 @@
 #include "SkColorPriv.h"
 #include "SkColorFilter.h"
 #include "SkDither.h"
-#include "sk_tool_utils.h"
 
 static void draw_sweep(SkCanvas* c, int width, int height, SkScalar angle) {
     SkRect  r;
@@ -112,7 +111,7 @@ public:
         make_bm(&fBM);
         make_bm(&fBMPreDither);
         pre_dither(fBMPreDither);
-        sk_tool_utils::copy_to(&fBM16, kARGB_4444_SkColorType, fBM);
+        fBM.copyTo(&fBM16, kARGB_4444_SkColorType);
 
         fAngle = 0;
 
index 2f3de35..e5f7369 100644 (file)
@@ -13,7 +13,6 @@
 #include "SkRegion.h"
 #include "SkUtils.h"
 #include "SkView.h"
-#include "sk_tool_utils.h"
 
 static void draw_rect(SkCanvas* canvas, const SkRect& r, const SkPaint& p) {
     canvas->drawRect(r, p);
@@ -78,7 +77,7 @@ public:
     DitherBitmapView() {
         fResult = test_pathregion();
         fBM8 = make_bitmap();
-        sk_tool_utils::copy_to(&fBM32, kN32_SkColorType, fBM8);
+        fBM8.copyTo(&fBM32, kN32_SkColorType);
 
         this->setBGColor(0xFFDDDDDD);
     }
index 00f3853..d12f804 100644 (file)
@@ -78,9 +78,9 @@ public:
 
     FilterView() {
         make_bm(&fBM8);
-        sk_tool_utils::copy_to(&fBM4444, kARGB_4444_SkColorType, fBM8);
-        sk_tool_utils::copy_to(&fBM16, kRGB_565_SkColorType, fBM8);
-        sk_tool_utils::copy_to(&fBM32, kN32_SkColorType, fBM8);
+        fBM8.copyTo(&fBM4444, kARGB_4444_SkColorType);
+        fBM8.copyTo(&fBM16, kRGB_565_SkColorType);
+        fBM8.copyTo(&fBM32, kN32_SkColorType);
 
         this->setBGColor(0xFFDDDDDD);
     }
index 1ba2968..8f131d1 100644 (file)
@@ -549,6 +549,7 @@ bool SkBitmap::canCopyTo(SkColorType dstCT) const {
         case kRGB_565_SkColorType:
         case kRGBA_8888_SkColorType:
         case kBGRA_8888_SkColorType:
+        case kRGBA_F16_SkColorType:
             break;
         case kGray_8_SkColorType:
             if (!sameConfigs) {
@@ -594,8 +595,7 @@ bool SkBitmap::writePixels(const SkPixmap& src, int dstX, int dstY,
     return true;
 }
 
-#ifdef SK_SUPPORT_LEGACY_BITMAP_COPYTO
-bool SkBitmap::copyTo(SkBitmap* dst, SkColorType dstColorType) const {
+bool SkBitmap::internalCopyTo(SkBitmap* dst, SkColorType dstColorType, Allocator* alloc) const {
     if (!this->canCopyTo(dstColorType)) {
         return false;
     }
@@ -605,8 +605,36 @@ bool SkBitmap::copyTo(SkBitmap* dst, SkColorType dstColorType) const {
         return false;
     }
 
-    SkBitmap tmpDst;
+    // Various Android specific compatibility modes.
+    // TODO:
+    // Move the logic of this entire function into the framework, then call readPixels() directly.
     SkImageInfo dstInfo = srcPM.info().makeColorType(dstColorType);
+    switch (dstColorType) {
+        case kRGB_565_SkColorType:
+            // copyTo() is not strict on alpha type.  Here we set the src to opaque to allow
+            // the call to readPixels() to succeed and preserve this lenient behavior.
+            if (kOpaque_SkAlphaType != srcPM.alphaType()) {
+                srcPM = SkPixmap(srcPM.info().makeAlphaType(kOpaque_SkAlphaType), srcPM.addr(),
+                                 srcPM.rowBytes(), srcPM.ctable());
+                dstInfo = dstInfo.makeAlphaType(kOpaque_SkAlphaType);
+            }
+            break;
+        case kRGBA_F16_SkColorType:
+            // The caller does not have an opportunity to pass a dst color space.  Assume that
+            // they want linear sRGB.
+            dstInfo = dstInfo.makeColorSpace(SkColorSpace::MakeSRGBLinear());
+
+            if (!srcPM.colorSpace()) {
+                // We can't do a sane conversion to F16 without a dst color space.  Guess sRGB
+                // in this case.
+                srcPM.setColorSpace(SkColorSpace::MakeSRGB());
+            }
+            break;
+        default:
+            break;
+    }
+
+    SkBitmap tmpDst;
     if (!tmpDst.setInfo(dstInfo)) {
         return false;
     }
@@ -616,7 +644,7 @@ bool SkBitmap::copyTo(SkBitmap* dst, SkColorType dstColorType) const {
     if (dstColorType == kIndex_8_SkColorType) {
         ctable.reset(SkRef(srcPM.ctable()));
     }
-    if (!tmpDst.tryAllocPixels(ctable.get())) {
+    if (!tmpDst.tryAllocPixels(alloc, ctable.get())) {
         return false;
     }
 
@@ -625,15 +653,60 @@ bool SkBitmap::copyTo(SkBitmap* dst, SkColorType dstColorType) const {
         return false;
     }
 
+    // We can't do a sane conversion from F16 without a src color space.  Guess sRGB in this case.
+    if (kRGBA_F16_SkColorType == srcPM.colorType() && !dstPM.colorSpace()) {
+        dstPM.setColorSpace(SkColorSpace::MakeSRGB());
+    }
+
+    // readPixels does not yet support color spaces with parametric transfer functions.  This
+    // works around that restriction when the color spaces are equal.
+    if (kRGBA_F16_SkColorType != dstColorType && kRGBA_F16_SkColorType != srcPM.colorType() &&
+            dstPM.colorSpace() == srcPM.colorSpace()) {
+        dstPM.setColorSpace(nullptr);
+        srcPM.setColorSpace(nullptr);
+    }
+
     if (!srcPM.readPixels(dstPM)) {
         return false;
     }
 
+    //  (for BitmapHeap) Clone the pixelref genID even though we have a new pixelref.
+    //  The old copyTo impl did this, so we continue it for now.
+    //
+    //  TODO: should we ignore rowbytes (i.e. getSize)? Then it could just be
+    //      if (src_pixelref->info == dst_pixelref->info)
+    //
+    if (srcPM.colorType() == dstColorType && tmpDst.getSize() == srcPM.getSize64()) {
+        SkPixelRef* dstPixelRef = tmpDst.pixelRef();
+        if (dstPixelRef->info() == fPixelRef->info()) {
+            dstPixelRef->cloneGenID(*fPixelRef);
+        }
+    }
+
     dst->swap(tmpDst);
     return true;
 }
+
+bool SkBitmap::copyTo(SkBitmap* dst, SkColorType ct) const {
+    return this->internalCopyTo(dst, ct, nullptr);
+}
+
+#ifdef SK_BUILD_FOR_ANDROID
+bool SkBitmap::copyTo(SkBitmap* dst, SkColorType ct, Allocator* alloc) const {
+    return this->internalCopyTo(dst, ct, alloc);
+}
 #endif
 
+// TODO: can we merge this with copyTo?
+bool SkBitmap::deepCopyTo(SkBitmap* dst) const {
+    const SkColorType dstCT = this->colorType();
+
+    if (!this->canCopyTo(dstCT)) {
+        return false;
+    }
+    return this->copyTo(dst, dstCT);
+}
+
 ///////////////////////////////////////////////////////////////////////////////
 
 static bool GetBitmapAlpha(const SkBitmap& src, uint8_t* SK_RESTRICT alpha, int alphaRowBytes) {
index c6d59ea..5834b66 100644 (file)
@@ -96,6 +96,20 @@ void SkPixelRef::needsNewGenID() {
     SkASSERT(!this->genIDIsUnique()); // This method isn't threadsafe, so the assert should be fine.
 }
 
+void SkPixelRef::cloneGenID(const SkPixelRef& that) {
+    // This is subtle.  We must call that.getGenerationID() to make sure its genID isn't 0.
+    uint32_t genID = that.getGenerationID();
+
+    // Neither ID is unique any more.
+    // (These & ~1u are actually redundant.  that.getGenerationID() just did it for us.)
+    this->fTaggedGenID.store(genID & ~1u);
+    that. fTaggedGenID.store(genID & ~1u);
+
+    // This method isn't threadsafe, so these asserts should be fine.
+    SkASSERT(!this->genIDIsUnique());
+    SkASSERT(!that. genIDIsUnique());
+}
+
 uint32_t SkPixelRef::getGenerationID() const {
     uint32_t id = fTaggedGenID.load();
     if (0 == id) {
index b22335b..a142576 100644 (file)
@@ -327,15 +327,13 @@ sk_sp<SkSpecialImage> SkSpecialImage::MakeFromRaster(const SkIRect& subset,
     }
 
     const SkBitmap* srcBM = &bm;
-    SkBitmap tmp;
+    SkBitmap tmpStorage;
     // ImageFilters only handle N32 at the moment, so force our src to be that
     if (!valid_for_imagefilters(bm.info())) {
-        if (!tmp.tryAllocPixels(bm.info().makeColorType(kN32_SkColorType)) ||
-            !bm.readPixels(tmp.info(), tmp.getPixels(), tmp.rowBytes(), 0, 0))
-        {
+        if (!bm.copyTo(&tmpStorage, kN32_SkColorType)) {
             return nullptr;
         }
-        srcBM = &tmp;
+        srcBM = &tmpStorage;
     }
     return sk_make_sp<SkSpecialImage_Raster>(subset, *srcBM, props);
 }
index b58aaf4..19460a4 100644 (file)
@@ -147,8 +147,7 @@ static const SkBitmap& not4444(const SkBitmap& input, SkBitmap* copy) {
         return input;
     }
     // ARGB_4444 is rarely used, so we can do a wasteful tmp copy.
-    copy->allocPixels(input.info().makeColorType(kN32_SkColorType));
-    SkAssertResult(input.readPixels(copy->info(), copy->getPixels(), copy->rowBytes(), 0, 0));
+    SkAssertResult(input.copyTo(copy, kN32_SkColorType));
     copy->setImmutable();
     return *copy;
 }
index 8c2a542..b3fd243 100644 (file)
@@ -89,10 +89,9 @@ bool SkEncodeImageWithCG(SkWStream* stream, const SkPixmap& pixmap, SkEncodedIma
             // <Error>: CGImageDestinationFinalize image destination does not have enough images
             // So instead we copy to 8888.
             if (bm.colorType() == kARGB_4444_SkColorType) {
-                SkBitmap bitmapN32;
-                bitmapN32.allocPixels(bm.info().makeColorType(kN32_SkColorType));
-                bm.readPixels(bitmapN32.info(), bitmapN32.getPixels(), bitmapN32.rowBytes(), 0, 0);
-                bm.swap(bitmapN32);
+                SkBitmap bitmap8888;
+                bm.copyTo(&bitmap8888, kN32_SkColorType);
+                bm.swap(bitmap8888);
             }
             type = kUTTypePNG;
             break;
index 1ae9257..6d355c1 100644 (file)
@@ -70,9 +70,7 @@ bool SkEncodeImageWithWIC(SkWStream* stream, const SkPixmap& pixmap,
 
     // First convert to BGRA if necessary.
     SkBitmap bitmap;
-    if (!bitmap.tryAllocPixels(bitmapOrig.info().makeColorType(kBGRA_8888_SkColorType)) ||
-        !bitmapOrig.readPixels(bitmap.info(), bitmap.getPixels(), bitmap.rowBytes(), 0, 0))
-    {
+    if (!bitmapOrig.copyTo(&bitmap, kBGRA_8888_SkColorType)) {
         return false;
     }
 
index b5df423..880c566 100644 (file)
@@ -110,10 +110,9 @@ static SkBitmap* prepareForImageRef(const SkBitmap& bm,
     SkBitmap* copy;
     if (upscaleTo32) {
         copy = new SkBitmap;
-        // here we make a deep copy of the pixels, since CG won't take our
+        // here we make a ceep copy of the pixels, since CG won't take our
         // 565 directly
-        copy->allocPixels(bm.info().makeColorType(kN32_SkColorType));
-        bm.readPixels(copy->info(), copy->getPixels(), copy->rowBytes(), 0, 0);
+        bm.copyTo(copy, kN32_SkColorType);
     } else {
         copy = new SkBitmap(bm);
     }
index dd5bf1a..aadf192 100644 (file)
@@ -9,7 +9,6 @@
 #include "SkRect.h"
 #include "SkTemplates.h"
 #include "Test.h"
-#include "sk_tool_utils.h"
 
 static void init_src(const SkBitmap& bitmap) {
     if (bitmap.getPixels()) {
@@ -113,7 +112,7 @@ DEF_TEST(BitmapCopy_extractSubset, reporter) {
             // Test copying an extracted subset.
             for (size_t j = 0; j < SK_ARRAY_COUNT(gPairs); j++) {
                 SkBitmap copy;
-                bool success = sk_tool_utils::copy_to(&copy, gPairs[j].fColorType, subset);
+                bool success = subset.copyTo(&copy, gPairs[j].fColorType);
                 if (!success) {
                     // Skip checking that success matches fValid, which is redundant
                     // with the code below.
@@ -237,3 +236,20 @@ DEF_TEST(BitmapReadPixels, reporter) {
         }
     }
 }
+
+DEF_TEST(BitmapCopy_ColorSpaceMatch, r) {
+    // We should support matching color spaces, even if they are parametric.
+    SkColorSpaceTransferFn fn;
+    fn.fA = 1.f; fn.fB = 0.f; fn.fC = 0.f; fn.fD = 0.f; fn.fE = 0.f; fn.fF = 0.f; fn.fG = 1.8f;
+    sk_sp<SkColorSpace> cs = SkColorSpace::MakeRGB(fn, SkColorSpace::kRec2020_Gamut);
+
+    SkImageInfo info = SkImageInfo::MakeN32Premul(1, 1, cs);
+    SkBitmap bitmap;
+    bitmap.allocPixels(info);
+    bitmap.eraseColor(0);
+
+    SkBitmap copy;
+    bool success = bitmap.copyTo(&copy, kN32_SkColorType);
+    REPORTER_ASSERT(r, success);
+    REPORTER_ASSERT(r, cs.get() == copy.colorSpace());
+}
index e0a7f78..0d4b785 100644 (file)
@@ -9,7 +9,6 @@
 #include "SkMallocPixelRef.h"
 #include "SkRandom.h"
 #include "Test.h"
-#include "sk_tool_utils.h"
 
 static void test_peekpixels(skiatest::Reporter* reporter) {
     const SkImageInfo info = SkImageInfo::MakeN32Premul(10, 10);
@@ -138,7 +137,7 @@ DEF_TEST(Bitmap_getColor_Swizzle, r) {
     };
     for (SkColorType ct : colorTypes) {
         SkBitmap copy;
-        if (!sk_tool_utils::copy_to(&copy, ct, source)) {
+        if (!source.copyTo(&copy, ct)) {
             ERRORF(r, "SkBitmap::copy failed %d", (int)ct);
             continue;
         }
index 24b9c13..79e03bd 100644 (file)
@@ -14,7 +14,6 @@
 
 #include "Resources.h"
 #include "Test.h"
-#include "sk_tool_utils.h"
 
 #include <initializer_list>
 #include <vector>
@@ -240,8 +239,7 @@ DEF_TEST(Codec_frames, r) {
                     // First copy the pixels from the cached frame
                     const int requiredFrame = frameInfos[index].fRequiredFrame;
                     if (requiredFrame != SkCodec::kNone) {
-                        const bool success = sk_tool_utils::copy_to(bm, kN32_SkColorType,
-                                cachedFrames[requiredFrame]);
+                        const bool success = cachedFrames[requiredFrame].copyTo(bm);
                         REPORTER_ASSERT(r, success);
                     }
                 }
index 4a13533..7944877 100644 (file)
@@ -850,7 +850,7 @@ DEF_TEST(Codec_pngChunkReader, r) {
 
     if (decodedBm.colorType() != bm.colorType()) {
         SkBitmap tmp;
-        bool success = sk_tool_utils::copy_to(&tmp, bm.colorType(), decodedBm);
+        bool success = decodedBm.copyTo(&tmp, bm.colorType());
         REPORTER_ASSERT(r, success);
         if (!success) {
             return;
index 23cc6b2..e386f46 100644 (file)
@@ -837,9 +837,7 @@ static SkBitmap* convert_colortype(SkBitmap* bitmap, SkColorType colorType) {
         return bitmap;
     }
     SkBitmap* dst = new SkBitmap();
-    if (dst->tryAllocPixels(bitmap->info().makeColorType(colorType)) &&
-        bitmap->readPixels(dst->info(), dst->getPixels(), dst->rowBytes(), 0, 0))
-    {
+    if (bitmap->copyTo(dst, colorType)) {
         delete bitmap;
         return dst;
     }
index bd32f19..27e91cc 100644 (file)
@@ -126,7 +126,7 @@ namespace sk_tools {
             // Convert smaller formats up to premul linear 8-bit (in SkPMColor order).
             if (bitmap.colorType() != kN32_SkColorType) {
                 SkBitmap n32;
-                if (!sk_tool_utils::copy_to(&n32, kN32_SkColorType, bitmap)) {
+                if (!bitmap.copyTo(&n32, kN32_SkColorType)) {
                     return nullptr;
                 }
                 bitmap = n32;
index c69b17d..9a4bb2b 100644 (file)
@@ -586,44 +586,6 @@ SkRect compute_tallest_occluder(const SkRRect& rr) {
     return SkRect::MakeLTRB(r.fLeft + maxL, r.fTop, r.fRight - maxR, r.fBottom);
 }
 
-bool copy_to(SkBitmap* dst, SkColorType dstColorType, const SkBitmap& src) {
-    SkPixmap srcPM;
-    if (!src.peekPixels(&srcPM)) {
-        return false;
-    }
-
-    SkBitmap tmpDst;
-    SkImageInfo dstInfo = srcPM.info().makeColorType(dstColorType);
-    if (!tmpDst.setInfo(dstInfo)) {
-        return false;
-    }
-
-    // allocate colortable if srcConfig == kIndex8_Config
-    sk_sp<SkColorTable> ctable = nullptr;
-    if (dstColorType == kIndex_8_SkColorType) {
-        if (src.colorType() != kIndex_8_SkColorType) {
-            return false;
-        }
-
-        ctable = sk_ref_sp(srcPM.ctable());
-    }
-    if (!tmpDst.tryAllocPixels(ctable.get())) {
-        return false;
-    }
-
-    SkPixmap dstPM;
-    if (!tmpDst.peekPixels(&dstPM)) {
-        return false;
-    }
-
-    if (!srcPM.readPixels(dstPM)) {
-        return false;
-    }
-
-    dst->swap(tmpDst);
-    return true;
-}
-
 void copy_to_g8(SkBitmap* dst, const SkBitmap& src) {
     SkASSERT(kBGRA_8888_SkColorType == src.colorType() ||
              kRGBA_8888_SkColorType == src.colorType());
index 111f966..e319411 100644 (file)
@@ -253,7 +253,6 @@ namespace sk_tool_utils {
         return sk_make_sp<EncodeImagePixelSerializer>();
     }
 
-    bool copy_to(SkBitmap* dst, SkColorType dstCT, const SkBitmap& src);
     void copy_to_g8(SkBitmap* dst, const SkBitmap& src);
 
 #if SK_SUPPORT_GPU
index 7a1b7e8..05e1c50 100644 (file)
@@ -80,7 +80,7 @@ static void force_all_opaque(const SkBitmap& bitmap) {
 
 bool write_bitmap(const SkString& path, const SkBitmap& bitmap) {
     SkBitmap copy;
-    sk_tool_utils::copy_to(&copy, kN32_SkColorType, bitmap);
+    bitmap.copyTo(&copy, kN32_SkColorType);
     force_all_opaque(copy);
     return sk_tool_utils::EncodeImageToFile(path.c_str(), copy,
                                       SkEncodedImageFormat::kPNG, 100);