diff options
author | Matt Sarett <msarett@google.com> | 2017-04-27 20:08:39 +0000 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2017-04-27 20:08:45 +0000 |
commit | 0122af08f6af0dee490e1a4f35b552377d0d4753 (patch) | |
tree | dc2a227b525f067fe8c837cc8d4c5c3480cb69de /src/core | |
parent | 4b32ab1b7cac09f42b0867f6c63cd8656dd9918d (diff) |
Revert "Delete copyTo(Allocator), hide copyTo() behind flag"
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>
Diffstat (limited to 'src/core')
-rw-r--r-- | src/core/SkBitmap.cpp | 81 | ||||
-rw-r--r-- | src/core/SkPixelRef.cpp | 14 | ||||
-rw-r--r-- | src/core/SkSpecialImage.cpp | 8 |
3 files changed, 94 insertions, 9 deletions
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); } |