diff options
30 files changed, 191 insertions, 118 deletions
@@ -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()); diff --git a/gm/all_bitmap_configs.cpp b/gm/all_bitmap_configs.cpp index 98d6621c6b..7e9dfab522 100644 --- a/gm/all_bitmap_configs.cpp +++ b/gm/all_bitmap_configs.cpp @@ -14,15 +14,8 @@ #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(©, colorType, *srcPtr); + src.copyTo(©, 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(¬N32bitmap, ct, n32bitmap)); + SkAssertResult(n32bitmap.copyTo(¬N32bitmap, ct)); SkASSERT(notN32bitmap.colorType() == ct); return SkImage::MakeFromBitmap(notN32bitmap); } diff --git a/gm/animatedGif.cpp b/gm/animatedGif.cpp index dd08abfd36..c7871e0d12 100644 --- a/gm/animatedGif.cpp +++ b/gm/animatedGif.cpp @@ -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; } } diff --git a/gm/bitmapcopy.cpp b/gm/bitmapcopy.cpp index 7428c20b50..60eecf2ecd 100644 --- a/gm/bitmapcopy.cpp +++ b/gm/bitmapcopy.cpp @@ -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)); diff --git a/gm/bitmapfilters.cpp b/gm/bitmapfilters.cpp index 7dc969286b..22e5d0943f 100644 --- a/gm/bitmapfilters.cpp +++ b/gm/bitmapfilters.cpp @@ -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: diff --git a/gm/copyTo4444.cpp b/gm/copyTo4444.cpp index f593a19de8..64f2c60746 100644 --- a/gm/copyTo4444.cpp +++ b/gm/copyTo4444.cpp @@ -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); } diff --git a/gm/showmiplevels.cpp b/gm/showmiplevels.cpp index 3e2091fd6b..e5374e4044 100644 --- a/gm/showmiplevels.cpp +++ b/gm/showmiplevels.cpp @@ -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); } /** diff --git a/gm/simpleaaclip.cpp b/gm/simpleaaclip.cpp index 4c7407dedb..8f6c5c95c5 100644 --- a/gm/simpleaaclip.cpp +++ b/gm/simpleaaclip.cpp @@ -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, diff --git a/include/core/SkBitmap.h b/include/core/SkBitmap.h index d38898ccef..8818829a41 100644 --- a/include/core/SkBitmap.h +++ b/include/core/SkBitmap.h @@ -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 */ diff --git a/include/core/SkPixelRef.h b/include/core/SkPixelRef.h index 6a86e59a86..342863f74e 100644 --- a/include/core/SkPixelRef.h +++ b/include/core/SkPixelRef.h @@ -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; diff --git a/public.bzl b/public.bzl index 9c41cdb2d5..01d70f7bcd 100644 --- a/public.bzl +++ b/public.bzl @@ -648,7 +648,6 @@ DEFINES_IOS = [ ] DEFINES_ALL = [ - "SK_SUPPORT_LEGACY_BITMAP_COPYTO", # Chrome DEFINES. "SK_USE_FLOATBITS", "SK_USE_FREETYPE_EMBOLDEN", diff --git a/samplecode/SampleDither.cpp b/samplecode/SampleDither.cpp index 6d91fda3ad..76ebecc25f 100644 --- a/samplecode/SampleDither.cpp +++ b/samplecode/SampleDither.cpp @@ -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; diff --git a/samplecode/SampleDitherBitmap.cpp b/samplecode/SampleDitherBitmap.cpp index 2f3de35fd6..e5f7369ae1 100644 --- a/samplecode/SampleDitherBitmap.cpp +++ b/samplecode/SampleDitherBitmap.cpp @@ -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); } diff --git a/samplecode/SampleFilter.cpp b/samplecode/SampleFilter.cpp index 00f3853d4e..d12f804d19 100644 --- a/samplecode/SampleFilter.cpp +++ b/samplecode/SampleFilter.cpp @@ -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); } diff --git a/src/core/SkBitmap.cpp b/src/core/SkBitmap.cpp index 1ba2968466..8f131d15f5 100644 --- a/src/core/SkBitmap.cpp +++ b/src/core/SkBitmap.cpp @@ -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) { diff --git a/src/core/SkPixelRef.cpp b/src/core/SkPixelRef.cpp index c6d59eab19..5834b66936 100644 --- a/src/core/SkPixelRef.cpp +++ b/src/core/SkPixelRef.cpp @@ -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) { diff --git a/src/core/SkSpecialImage.cpp b/src/core/SkSpecialImage.cpp index b22335bb75..a142576c2e 100644 --- a/src/core/SkSpecialImage.cpp +++ b/src/core/SkSpecialImage.cpp @@ -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); } diff --git a/src/pdf/SkPDFBitmap.cpp b/src/pdf/SkPDFBitmap.cpp index b58aaf48a5..19460a44f0 100644 --- a/src/pdf/SkPDFBitmap.cpp +++ b/src/pdf/SkPDFBitmap.cpp @@ -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; } diff --git a/src/ports/SkImageEncoder_CG.cpp b/src/ports/SkImageEncoder_CG.cpp index 8c2a542fc3..b3fd243324 100644 --- a/src/ports/SkImageEncoder_CG.cpp +++ b/src/ports/SkImageEncoder_CG.cpp @@ -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; diff --git a/src/ports/SkImageEncoder_WIC.cpp b/src/ports/SkImageEncoder_WIC.cpp index 1ae9257395..6d355c1d47 100644 --- a/src/ports/SkImageEncoder_WIC.cpp +++ b/src/ports/SkImageEncoder_WIC.cpp @@ -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; } diff --git a/src/utils/mac/SkCreateCGImageRef.cpp b/src/utils/mac/SkCreateCGImageRef.cpp index b5df42364b..880c566c73 100644 --- a/src/utils/mac/SkCreateCGImageRef.cpp +++ b/src/utils/mac/SkCreateCGImageRef.cpp @@ -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); } diff --git a/tests/BitmapCopyTest.cpp b/tests/BitmapCopyTest.cpp index dd5bf1afde..aadf192285 100644 --- a/tests/BitmapCopyTest.cpp +++ b/tests/BitmapCopyTest.cpp @@ -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(©, gPairs[j].fColorType, subset); + bool success = subset.copyTo(©, 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(©, kN32_SkColorType); + REPORTER_ASSERT(r, success); + REPORTER_ASSERT(r, cs.get() == copy.colorSpace()); +} diff --git a/tests/BitmapTest.cpp b/tests/BitmapTest.cpp index e0a7f78d8b..0d4b785231 100644 --- a/tests/BitmapTest.cpp +++ b/tests/BitmapTest.cpp @@ -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(©, ct, source)) { + if (!source.copyTo(©, ct)) { ERRORF(r, "SkBitmap::copy failed %d", (int)ct); continue; } diff --git a/tests/CodecAnimTest.cpp b/tests/CodecAnimTest.cpp index 24b9c13ae9..79e03bdef8 100644 --- a/tests/CodecAnimTest.cpp +++ b/tests/CodecAnimTest.cpp @@ -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); } } diff --git a/tests/CodecTest.cpp b/tests/CodecTest.cpp index 4a135337a7..7944877702 100644 --- a/tests/CodecTest.cpp +++ b/tests/CodecTest.cpp @@ -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; diff --git a/tools/debugger/SkDrawCommand.cpp b/tools/debugger/SkDrawCommand.cpp index 23cc6b21f8..e386f46f22 100644 --- a/tools/debugger/SkDrawCommand.cpp +++ b/tools/debugger/SkDrawCommand.cpp @@ -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; } diff --git a/tools/picture_utils.cpp b/tools/picture_utils.cpp index bd32f1938e..27e91ccdeb 100644 --- a/tools/picture_utils.cpp +++ b/tools/picture_utils.cpp @@ -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; diff --git a/tools/sk_tool_utils.cpp b/tools/sk_tool_utils.cpp index c69b17d720..9a4bb2ba8c 100644 --- a/tools/sk_tool_utils.cpp +++ b/tools/sk_tool_utils.cpp @@ -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()); diff --git a/tools/sk_tool_utils.h b/tools/sk_tool_utils.h index 111f966983..e319411349 100644 --- a/tools/sk_tool_utils.h +++ b/tools/sk_tool_utils.h @@ -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 diff --git a/tools/skdiff/skdiff_utils.cpp b/tools/skdiff/skdiff_utils.cpp index 7a1b7e88a4..05e1c50388 100644 --- a/tools/skdiff/skdiff_utils.cpp +++ b/tools/skdiff/skdiff_utils.cpp @@ -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(©, kN32_SkColorType, bitmap); + bitmap.copyTo(©, kN32_SkColorType); force_all_opaque(copy); return sk_tool_utils::EncodeImageToFile(path.c_str(), copy, SkEncodedImageFormat::kPNG, 100); |