diff options
author | robertphillips <robertphillips@google.com> | 2016-03-16 09:47:08 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2016-03-16 09:47:08 -0700 |
commit | 250581493a0859987e482810879e85e5ac2dc002 (patch) | |
tree | 2a9432c347327c16d35a15f6a6b8b53b7704aef3 | |
parent | b3b6beae044ca457edf99cf223cd6379a49d4ef0 (diff) |
Add SkSpecialImage::extractSubset & NewFromPixmap
This is calved off of: https://codereview.chromium.org/1785643003/ (Switch SkBlurImageFilter over to new onFilterImage interface)
GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1787883002
Review URL: https://codereview.chromium.org/1787883002
-rw-r--r-- | bench/CoverageBench.cpp | 1 | ||||
-rw-r--r-- | bench/PDFBench.cpp | 1 | ||||
-rw-r--r-- | gm/image.cpp | 1 | ||||
-rw-r--r-- | gyp/core.gypi | 2 | ||||
-rw-r--r-- | include/core/SkPixmap.h | 65 | ||||
-rw-r--r-- | src/core/SkAutoPixmapStorage.cpp | 64 | ||||
-rw-r--r-- | src/core/SkAutoPixmapStorage.h | 87 | ||||
-rw-r--r-- | src/core/SkPixmap.cpp | 48 | ||||
-rw-r--r-- | src/core/SkScalerContext.cpp | 1 | ||||
-rw-r--r-- | src/core/SkSpecialImage.cpp | 87 | ||||
-rw-r--r-- | src/core/SkSpecialImage.h | 39 | ||||
-rw-r--r-- | src/gpu/GrSWMaskHelper.h | 1 | ||||
-rw-r--r-- | src/image/SkImage_Gpu.cpp | 1 | ||||
-rw-r--r-- | tests/DeviceLooperTest.cpp | 1 | ||||
-rw-r--r-- | tests/Float16Test.cpp | 1 | ||||
-rw-r--r-- | tests/ImageTest.cpp | 1 | ||||
-rw-r--r-- | tests/SpecialImageTest.cpp | 99 | ||||
-rw-r--r-- | tests/TestingSpecialImageAccess.h | 2 | ||||
-rw-r--r-- | tests/TextureCompressionTest.cpp | 1 |
19 files changed, 346 insertions, 157 deletions
diff --git a/bench/CoverageBench.cpp b/bench/CoverageBench.cpp index 3dee66836f..ebde4208a0 100644 --- a/bench/CoverageBench.cpp +++ b/bench/CoverageBench.cpp @@ -6,6 +6,7 @@ */ #include "Benchmark.h" +#include "SkAutoPixmapStorage.h" #include "SkBitmap.h" #include "SkCanvas.h" #include "SkColorPriv.h" diff --git a/bench/PDFBench.cpp b/bench/PDFBench.cpp index b7f48daac8..ba25e44f37 100644 --- a/bench/PDFBench.cpp +++ b/bench/PDFBench.cpp @@ -7,6 +7,7 @@ #include "Benchmark.h" #include "Resources.h" +#include "SkAutoPixmapStorage.h" #include "SkData.h" #include "SkImage.h" #include "SkPDFBitmap.h" diff --git a/gm/image.cpp b/gm/image.cpp index 2ddda8f8a4..4e22dd0ff5 100644 --- a/gm/image.cpp +++ b/gm/image.cpp @@ -7,6 +7,7 @@ #include <functional> #include "gm.h" +#include "SkAutoPixmapStorage.h" #include "SkData.h" #include "SkCanvas.h" #include "SkRandom.h" diff --git a/gyp/core.gypi b/gyp/core.gypi index 15af4649a1..b9ee244a5f 100644 --- a/gyp/core.gypi +++ b/gyp/core.gypi @@ -23,6 +23,8 @@ '<(skia_src_path)/core/SkAlphaRuns.cpp', '<(skia_src_path)/core/SkAntiRun.h', '<(skia_src_path)/core/SkAutoKern.h', + '<(skia_src_path)/core/SkAutoPixmapStorage.h', + '<(skia_src_path)/core/SkAutoPixmapStorage.cpp', '<(skia_src_path)/core/SkBBHFactory.cpp', '<(skia_src_path)/core/SkBBoxHierarchy.h', '<(skia_src_path)/core/SkBigPicture.cpp', diff --git a/include/core/SkPixmap.h b/include/core/SkPixmap.h index b43072b957..3a7abdf134 100644 --- a/include/core/SkPixmap.h +++ b/include/core/SkPixmap.h @@ -187,71 +187,6 @@ private: ///////////////////////////////////////////////////////////////////////////////////////////// -class SK_API SkAutoPixmapStorage : public SkPixmap { -public: - SkAutoPixmapStorage(); - ~SkAutoPixmapStorage(); - - /** - * Try to allocate memory for the pixels needed to match the specified Info. On success - * return true and fill out the pixmap to point to that memory. The storage will be freed - * when this object is destroyed, or if another call to tryAlloc() or alloc() is made. - * - * On failure, return false and reset() the pixmap to empty. - */ - bool tryAlloc(const SkImageInfo&); - - /** - * Allocate memory for the pixels needed to match the specified Info and fill out the pixmap - * to point to that memory. The storage will be freed when this object is destroyed, - * or if another call to tryAlloc() or alloc() is made. - * - * If the memory cannot be allocated, calls sk_throw(). - */ - void alloc(const SkImageInfo&); - - /** - * Gets the size and optionally the rowBytes that would be allocated by SkAutoPixmapStorage if - * alloc/tryAlloc was called. - */ - static size_t AllocSize(const SkImageInfo& info, size_t* rowBytes); - - /** - * Returns an SkData object wrapping the allocated pixels memory, and resets the pixmap. - * If the storage hasn't been allocated, the result is NULL. - */ - const SkData* SK_WARN_UNUSED_RESULT detachPixelsAsData(); - - // We wrap these so we can clear our internal storage - - void reset() { - this->freeStorage(); - this->INHERITED::reset(); - } - void reset(const SkImageInfo& info, const void* addr, size_t rb, SkColorTable* ctable = NULL) { - this->freeStorage(); - this->INHERITED::reset(info, addr, rb, ctable); - } - void reset(const SkImageInfo& info) { - this->freeStorage(); - this->INHERITED::reset(info); - } - bool SK_WARN_UNUSED_RESULT reset(const SkMask& mask) { - this->freeStorage(); - return this->INHERITED::reset(mask); - } - -private: - void* fStorage; - - void freeStorage() { - sk_free(fStorage); - fStorage = nullptr; - } - - typedef SkPixmap INHERITED; -}; - ///////////////////////////////////////////////////////////////////////////////////////////// class SK_API SkAutoPixmapUnlock : ::SkNoncopyable { diff --git a/src/core/SkAutoPixmapStorage.cpp b/src/core/SkAutoPixmapStorage.cpp new file mode 100644 index 0000000000..3be28a94c4 --- /dev/null +++ b/src/core/SkAutoPixmapStorage.cpp @@ -0,0 +1,64 @@ + +/* + * Copyright 2016 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "SkAutoPixmapStorage.h" +#include "SkData.h" + +SkAutoPixmapStorage::SkAutoPixmapStorage() : fStorage(nullptr) {} + +SkAutoPixmapStorage::~SkAutoPixmapStorage() { + this->freeStorage(); +} + +size_t SkAutoPixmapStorage::AllocSize(const SkImageInfo& info, size_t* rowBytes) { + size_t rb = info.minRowBytes(); + if (rowBytes) { + *rowBytes = rb; + } + return info.getSafeSize(rb); +} + +bool SkAutoPixmapStorage::tryAlloc(const SkImageInfo& info) { + this->freeStorage(); + + size_t rb; + size_t size = AllocSize(info, &rb); + if (0 == size) { + return false; + } + void* pixels = sk_malloc_flags(size, 0); + if (nullptr == pixels) { + return false; + } + this->reset(info, pixels, rb); + fStorage = pixels; + return true; +} + +void SkAutoPixmapStorage::alloc(const SkImageInfo& info) { + if (!this->tryAlloc(info)) { + sk_throw(); + } +} + +const SkData* SkAutoPixmapStorage::detachPixelsAsData() { + if (!fStorage) { + return nullptr; + } + + auto data = SkData::MakeFromMalloc(fStorage, this->getSafeSize()); + fStorage = nullptr; + this->INHERITED::reset(); + + return data.release(); +} + +void SkAutoPixmapStorage::release() { + fStorage = nullptr; + this->INHERITED::reset(); +} diff --git a/src/core/SkAutoPixmapStorage.h b/src/core/SkAutoPixmapStorage.h new file mode 100644 index 0000000000..4379b13d24 --- /dev/null +++ b/src/core/SkAutoPixmapStorage.h @@ -0,0 +1,87 @@ + +/* + * Copyright 2016 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef SkAutoPixmapStorage_DEFINED +#define SkAutoPixmapStorage_DEFINED + +#include "SkPixmap.h" + +class SK_API SkAutoPixmapStorage : public SkPixmap { +public: + SkAutoPixmapStorage(); + ~SkAutoPixmapStorage(); + + /** + * Try to allocate memory for the pixels needed to match the specified Info. On success + * return true and fill out the pixmap to point to that memory. The storage will be freed + * when this object is destroyed, or if another call to tryAlloc() or alloc() is made. + * + * On failure, return false and reset() the pixmap to empty. + */ + bool tryAlloc(const SkImageInfo&); + + /** + * Allocate memory for the pixels needed to match the specified Info and fill out the pixmap + * to point to that memory. The storage will be freed when this object is destroyed, + * or if another call to tryAlloc() or alloc() is made. + * + * If the memory cannot be allocated, calls sk_throw(). + */ + void alloc(const SkImageInfo&); + + /** + * Gets the size and optionally the rowBytes that would be allocated by SkAutoPixmapStorage if + * alloc/tryAlloc was called. + */ + static size_t AllocSize(const SkImageInfo& info, size_t* rowBytes); + + /** + * Returns an SkData object wrapping the allocated pixels memory, and resets the pixmap. + * If the storage hasn't been allocated, the result is NULL. + */ + const SkData* SK_WARN_UNUSED_RESULT detachPixelsAsData(); + + /** + * Whereas 'reset' frees the backing memory and then clears the SkPixmap, + * this entry point disowns the backing memory before clearing so the memory + * isn't freed. It can be used when the Pixmap has been installed into + * an SkBitmap and the SkBitmap should manage the memory's lifetime. + */ + void release(); + + // We wrap these so we can clear our internal storage + + void reset() { + this->freeStorage(); + this->INHERITED::reset(); + } + void reset(const SkImageInfo& info, const void* addr, size_t rb, SkColorTable* ctable = NULL) { + this->freeStorage(); + this->INHERITED::reset(info, addr, rb, ctable); + } + void reset(const SkImageInfo& info) { + this->freeStorage(); + this->INHERITED::reset(info); + } + bool SK_WARN_UNUSED_RESULT reset(const SkMask& mask) { + this->freeStorage(); + return this->INHERITED::reset(mask); + } + +private: + void* fStorage; + + void freeStorage() { + sk_free(fStorage); + fStorage = nullptr; + } + + typedef SkPixmap INHERITED; +}; + +#endif diff --git a/src/core/SkPixmap.cpp b/src/core/SkPixmap.cpp index f7672d082f..aa1d213bf6 100644 --- a/src/core/SkPixmap.cpp +++ b/src/core/SkPixmap.cpp @@ -281,51 +281,3 @@ bool SkPixmap::scalePixels(const SkPixmap& dst, SkFilterQuality quality) const { ////////////////////////////////////////////////////////////////////////////////////////////////// -SkAutoPixmapStorage::SkAutoPixmapStorage() : fStorage(nullptr) {} - -SkAutoPixmapStorage::~SkAutoPixmapStorage() { - this->freeStorage(); -} - -size_t SkAutoPixmapStorage::AllocSize(const SkImageInfo& info, size_t* rowBytes) { - size_t rb = info.minRowBytes(); - if (rowBytes) { - *rowBytes = rb; - } - return info.getSafeSize(rb); -} - -bool SkAutoPixmapStorage::tryAlloc(const SkImageInfo& info) { - this->freeStorage(); - - size_t rb; - size_t size = AllocSize(info, &rb); - if (0 == size) { - return false; - } - void* pixels = sk_malloc_flags(size, 0); - if (nullptr == pixels) { - return false; - } - this->reset(info, pixels, rb); - fStorage = pixels; - return true; -} - -void SkAutoPixmapStorage::alloc(const SkImageInfo& info) { - if (!this->tryAlloc(info)) { - sk_throw(); - } -} - -const SkData* SkAutoPixmapStorage::detachPixelsAsData() { - if (!fStorage) { - return nullptr; - } - - auto data = SkData::MakeFromMalloc(fStorage, this->getSafeSize()); - fStorage = nullptr; - this->INHERITED::reset(); - - return data.release(); -} diff --git a/src/core/SkScalerContext.cpp b/src/core/SkScalerContext.cpp index a479c3782f..5e125f3008 100644 --- a/src/core/SkScalerContext.cpp +++ b/src/core/SkScalerContext.cpp @@ -8,6 +8,7 @@ #include "SkScalerContext.h" +#include "SkAutoPixmapStorage.h" #include "SkColorPriv.h" #include "SkDescriptor.h" #include "SkDraw.h" diff --git a/src/core/SkSpecialImage.cpp b/src/core/SkSpecialImage.cpp index a55fe65029..b17d5d4147 100644 --- a/src/core/SkSpecialImage.cpp +++ b/src/core/SkSpecialImage.cpp @@ -20,7 +20,7 @@ public: virtual void onDraw(SkCanvas*, SkScalar x, SkScalar y, const SkPaint*) const = 0; - virtual bool testingOnlyOnPeekPixels(SkPixmap*) const { return false; } + virtual bool onPeekPixels(SkPixmap*) const { return false; } virtual GrTexture* onPeekTexture() const { return nullptr; } @@ -29,7 +29,9 @@ public: // Delete this entry point ASAP (see skbug.com/4965) virtual bool getBitmapDeprecated(SkBitmap* result) const = 0; - virtual SkSpecialSurface* onNewSurface(const SkImageInfo& info) const { return nullptr; } + virtual SkSpecialSurface* onNewSurface(const SkImageInfo& info) const = 0; + + virtual SkSpecialImage* onExtractSubset(const SkIRect& subset) const = 0; private: typedef SkSpecialImage INHERITED; @@ -44,8 +46,8 @@ void SkSpecialImage::draw(SkCanvas* canvas, SkScalar x, SkScalar y, const SkPain return as_SIB(this)->onDraw(canvas, x, y, paint); } -bool SkSpecialImage::testingOnlyPeekPixels(SkPixmap* pixmap) const { - return as_SIB(this)->testingOnlyOnPeekPixels(pixmap); +bool SkSpecialImage::peekPixels(SkPixmap* pixmap) const { + return as_SIB(this)->onPeekPixels(pixmap); } GrTexture* SkSpecialImage::peekTexture() const { @@ -60,6 +62,10 @@ SkSpecialSurface* SkSpecialImage::newSurface(const SkImageInfo& info) const { return as_SIB(this)->onNewSurface(info); } +SkSpecialImage* SkSpecialImage::extractSubset(const SkIRect& subset) const { + return as_SIB(this)->onExtractSubset(subset); +} + #if SK_SUPPORT_GPU #include "SkGr.h" #include "SkGrPixelRef.h" @@ -85,8 +91,7 @@ bool SkSpecialImage::internal_getBM(SkBitmap* result) { return ib->getBitmapDeprecated(result); } -SkImageFilter::Proxy* SkSpecialImage::internal_getProxy() { - SkASSERT(fProxy); +SkImageFilter::Proxy* SkSpecialImage::internal_getProxy() const { return fProxy; } @@ -129,7 +134,7 @@ public: dst, paint, SkCanvas::kStrict_SrcRectConstraint); } - bool testingOnlyOnPeekPixels(SkPixmap* pixmap) const override { + bool onPeekPixels(SkPixmap* pixmap) const override { return fImage->peekPixels(pixmap); } @@ -170,6 +175,17 @@ public: return SkSpecialSurface::NewRaster(this->proxy(), info, nullptr); } + SkSpecialImage* onExtractSubset(const SkIRect& subset) const override { + SkAutoTUnref<SkImage> subsetImg(fImage->newSubset(subset)); + if (!subsetImg) { + return nullptr; + } + + return SkSpecialImage::NewFromImage(this->internal_getProxy(), + SkIRect::MakeWH(subset.width(), subset.height()), + subsetImg); + } + private: SkAutoTUnref<const SkImage> fImage; @@ -214,6 +230,17 @@ public: } } + SkSpecialImage_Raster(SkImageFilter::Proxy* proxy, + const SkIRect& subset, + const SkPixmap& pixmap, + void (*releaseProc)(void* addr, void* context), + void* context) + : INHERITED(proxy, subset, kNeedNewImageUniqueID_SpecialImage) { + fBitmap.installPixels(pixmap.info(), pixmap.writable_addr(), + pixmap.rowBytes(), pixmap.ctable(), + releaseProc, context); + } + ~SkSpecialImage_Raster() override { } bool isOpaque() const override { return fBitmap.isOpaque(); } @@ -228,19 +255,13 @@ public: dst, paint, SkCanvas::kStrict_SrcRectConstraint); } - bool testingOnlyOnPeekPixels(SkPixmap* pixmap) const override { + bool onPeekPixels(SkPixmap* pixmap) const override { const SkImageInfo info = fBitmap.info(); if ((kUnknown_SkColorType == info.colorType()) || !fBitmap.getPixels()) { return false; } - const void* pixels = fBitmap.getPixels(); - if (pixels) { - if (pixmap) { - pixmap->reset(info, pixels, fBitmap.rowBytes()); - } - return true; - } - return false; + + return fBitmap.peekPixels(pixmap); } bool getBitmapDeprecated(SkBitmap* result) const override { @@ -257,6 +278,18 @@ public: return SkSpecialSurface::NewRaster(this->proxy(), info, nullptr); } + SkSpecialImage* onExtractSubset(const SkIRect& subset) const override { + SkBitmap subsetBM; + + if (!fBitmap.extractSubset(&subsetBM, subset)) { + return nullptr; + } + + return SkSpecialImage::NewFromRaster(this->internal_getProxy(), + SkIRect::MakeWH(subset.width(), subset.height()), + subsetBM); + } + private: SkBitmap fBitmap; @@ -271,6 +304,15 @@ SkSpecialImage* SkSpecialImage::NewFromRaster(SkImageFilter::Proxy* proxy, return new SkSpecialImage_Raster(proxy, subset, bm); } +SkSpecialImage* SkSpecialImage::NewFromPixmap(SkImageFilter::Proxy* proxy, + const SkIRect& subset, + const SkPixmap& src, + void (*releaseProc)(void* addr, void* context), + void* context) { + return new SkSpecialImage_Raster(proxy, subset, src, releaseProc, context); +} + + #if SK_SUPPORT_GPU /////////////////////////////////////////////////////////////////////////////// #include "GrTexture.h" @@ -315,7 +357,10 @@ public: return false; } - result->setPixelRef(new SkGrPixelRef(info, fTexture))->unref(); + const SkImageInfo prInfo = info.makeWH(fTexture->width(), fTexture->height()); + + SkAutoTUnref<SkGrPixelRef> pixelRef(new SkGrPixelRef(prInfo, fTexture)); + result->setPixelRef(pixelRef, this->subset().fLeft, this->subset().fTop); return true; } @@ -345,6 +390,14 @@ public: return SkSpecialSurface::NewRenderTarget(this->proxy(), fTexture->getContext(), desc); } + SkSpecialImage* onExtractSubset(const SkIRect& subset) const override { + return SkSpecialImage::NewFromGpu(this->internal_getProxy(), + subset, + this->uniqueID(), + fTexture, + fAlphaType); + } + private: SkAutoTUnref<GrTexture> fTexture; const SkAlphaType fAlphaType; diff --git a/src/core/SkSpecialImage.h b/src/core/SkSpecialImage.h index e90de097fb..b1b6a28d6a 100644 --- a/src/core/SkSpecialImage.h +++ b/src/core/SkSpecialImage.h @@ -63,16 +63,27 @@ public: uint32_t uniqueID, GrTexture*, SkAlphaType at = kPremul_SkAlphaType); + static SkSpecialImage* NewFromPixmap(SkImageFilter::Proxy*, + const SkIRect& subset, + const SkPixmap&, + void (*releaseProc)(void* addr, void* context), + void* context); /** * Create a new surface with a backend that is compatible with this image. */ SkSpecialSurface* newSurface(const SkImageInfo&) const; + /** + * Extract a subset of this special image and return it as a special image. + * It may or may not point to the same backing memory. + */ + SkSpecialImage* extractSubset(const SkIRect& subset) const; + // These three internal methods will go away (see skbug.com/4965) bool internal_getBM(SkBitmap* result); static SkSpecialImage* internal_fromBM(SkImageFilter::Proxy*, const SkBitmap&); - SkImageFilter::Proxy* internal_getProxy(); + SkImageFilter::Proxy* internal_getProxy() const; // TODO: hide this when GrLayerHoister uses SkSpecialImages more fully (see skbug.com/5063) /** @@ -81,6 +92,20 @@ public: */ GrTexture* peekTexture() const; + // TODO: hide this whe the imagefilter all have a consistent draw path (see skbug.com/5063) + /** + * If the SpecialImage is backed by cpu pixels, return the const address + * of those pixels and, if not null, the ImageInfo, rowBytes, and, if present, + * the color table. The returned address(es) is/are only valid while the image object + * is in scope. + * + * The returned ImageInfo represents the backing memory. Use 'subset' + * to get the active portion's dimensions. + * + * On failure, return false and ignore the pixmap parameter. + */ + bool peekPixels(SkPixmap*) const; + protected: SkSpecialImage(SkImageFilter::Proxy* proxy, const SkIRect& subset, uint32_t uniqueID) : fSubset(subset) @@ -93,18 +118,6 @@ protected: friend class TestingSpecialImageAccess; friend class TestingSpecialSurfaceAccess; - /** - * If the SpecialImage is backed by cpu pixels, return the const address - * of those pixels and, if not null, return the ImageInfo and rowBytes. - * The returned address is only valid while the image object is in scope. - * - * The returned ImageInfo represents the backing memory. Use 'subset' - * to get the active portion's dimensions. - * - * On failure, return false and ignore the pixmap parameter. - */ - bool testingOnlyPeekPixels(SkPixmap*) const; - // This entry point is for testing only. It does a readback from VRAM for // GPU-backed special images. bool testingOnlyGetROPixels(SkBitmap*) const; diff --git a/src/gpu/GrSWMaskHelper.h b/src/gpu/GrSWMaskHelper.h index b90205b1a1..fb5d9e86aa 100644 --- a/src/gpu/GrSWMaskHelper.h +++ b/src/gpu/GrSWMaskHelper.h @@ -8,6 +8,7 @@ #ifndef GrSWMaskHelper_DEFINED #define GrSWMaskHelper_DEFINED +#include "SkAutoPixmapStorage.h" #include "GrColor.h" #include "GrPipelineBuilder.h" #include "SkBitmap.h" diff --git a/src/image/SkImage_Gpu.cpp b/src/image/SkImage_Gpu.cpp index cde4232d36..5e687b751a 100644 --- a/src/image/SkImage_Gpu.cpp +++ b/src/image/SkImage_Gpu.cpp @@ -5,6 +5,7 @@ * found in the LICENSE file. */ +#include "SkAutoPixmapStorage.h" #include "GrCaps.h" #include "GrContext.h" #include "GrDrawContext.h" diff --git a/tests/DeviceLooperTest.cpp b/tests/DeviceLooperTest.cpp index 1a51b58980..c8eb3c7b75 100644 --- a/tests/DeviceLooperTest.cpp +++ b/tests/DeviceLooperTest.cpp @@ -5,6 +5,7 @@ * found in the LICENSE file. */ +#include "SkAutoPixmapStorage.h" #include "SkDeviceLooper.h" #include "SkRasterClip.h" #include "Test.h" diff --git a/tests/Float16Test.cpp b/tests/Float16Test.cpp index ef349c6cb6..6a7f9842f4 100644 --- a/tests/Float16Test.cpp +++ b/tests/Float16Test.cpp @@ -6,6 +6,7 @@ */ #include "Test.h" +#include "SkAutoPixmapStorage.h" #include "SkColor.h" #include "SkHalf.h" #include "SkOpts.h" diff --git a/tests/ImageTest.cpp b/tests/ImageTest.cpp index 3c2c31cca9..da9268dded 100644 --- a/tests/ImageTest.cpp +++ b/tests/ImageTest.cpp @@ -9,6 +9,7 @@ #include <initializer_list> #include "DMGpuSupport.h" +#include "SkAutoPixmapStorage.h" #include "SkBitmap.h" #include "SkCanvas.h" #include "SkData.h" diff --git a/tests/SpecialImageTest.cpp b/tests/SpecialImageTest.cpp index 9bde7eec33..7511e62971 100644 --- a/tests/SpecialImageTest.cpp +++ b/tests/SpecialImageTest.cpp @@ -5,9 +5,11 @@ * found in the LICENSE file */ +#include "SkAutoPixmapStorage.h" #include "SkBitmap.h" #include "SkCanvas.h" #include "SkImage.h" +#include "SkPixmap.h" #include "SkSpecialImage.h" #include "SkSpecialSurface.h" #include "Test.h" @@ -48,10 +50,11 @@ static SkBitmap create_bm() { // Basic test of the SkSpecialImage public API (e.g., peekTexture, peekPixels & draw) static void test_image(SkSpecialImage* img, skiatest::Reporter* reporter, - bool peekPixelsSucceeds, bool peekTextureSucceeds) { + bool peekPixelsSucceeds, bool peekTextureSucceeds, + int offset, int size) { const SkIRect subset = TestingSpecialImageAccess::Subset(img); - REPORTER_ASSERT(reporter, kPad == subset.left()); - REPORTER_ASSERT(reporter, kPad == subset.top()); + REPORTER_ASSERT(reporter, offset == subset.left()); + REPORTER_ASSERT(reporter, offset == subset.top()); REPORTER_ASSERT(reporter, kSmallerSize == subset.width()); REPORTER_ASSERT(reporter, kSmallerSize == subset.height()); @@ -63,8 +66,8 @@ static void test_image(SkSpecialImage* img, skiatest::Reporter* reporter, REPORTER_ASSERT(reporter, peekPixelsSucceeds == !!TestingSpecialImageAccess::PeekPixels(img, &pixmap)); if (peekPixelsSucceeds) { - REPORTER_ASSERT(reporter, kFullSize == pixmap.width()); - REPORTER_ASSERT(reporter, kFullSize == pixmap.height()); + REPORTER_ASSERT(reporter, size == pixmap.width()); + REPORTER_ASSERT(reporter, size == pixmap.height()); } //-------------- @@ -95,10 +98,22 @@ static void test_image(SkSpecialImage* img, skiatest::Reporter* reporter, DEF_TEST(SpecialImage_Raster, reporter) { SkBitmap bm = create_bm(); + SkAutoTUnref<SkSpecialImage> fullSImage(SkSpecialImage::NewFromRaster( + nullptr, + SkIRect::MakeWH(kFullSize, kFullSize), + bm)); + const SkIRect& subset = SkIRect::MakeXYWH(kPad, kPad, kSmallerSize, kSmallerSize); - SkAutoTUnref<SkSpecialImage> img(SkSpecialImage::NewFromRaster(nullptr, subset, bm)); - test_image(img, reporter, true, false); + { + SkAutoTUnref<SkSpecialImage> subSImg1(SkSpecialImage::NewFromRaster(nullptr, subset, bm)); + test_image(subSImg1, reporter, true, false, kPad, kFullSize); + } + + { + SkAutoTUnref<SkSpecialImage> subSImg2(fullSImage->extractSubset(subset)); + test_image(subSImg2, reporter, true, false, 0, kSmallerSize); + } } DEF_TEST(SpecialImage_Image, reporter) { @@ -106,12 +121,56 @@ DEF_TEST(SpecialImage_Image, reporter) { SkAutoTUnref<SkImage> fullImage(SkImage::NewFromBitmap(bm)); + SkAutoTUnref<SkSpecialImage> fullSImage(SkSpecialImage::NewFromImage( + nullptr, + SkIRect::MakeWH(kFullSize, kFullSize), + fullImage)); + const SkIRect& subset = SkIRect::MakeXYWH(kPad, kPad, kSmallerSize, kSmallerSize); - SkAutoTUnref<SkSpecialImage> img(SkSpecialImage::NewFromImage(nullptr, subset, fullImage)); - test_image(img, reporter, true, false); + { + SkAutoTUnref<SkSpecialImage> subSImg1(SkSpecialImage::NewFromImage(nullptr, + subset, + fullImage)); + test_image(subSImg1, reporter, true, false, kPad, kFullSize); + } + + { + SkAutoTUnref<SkSpecialImage> subSImg2(fullSImage->extractSubset(subset)); + test_image(subSImg2, reporter, true, false, 0, kSmallerSize); + } } +DEF_TEST(SpecialImage_Pixmap, reporter) { + SkAutoPixmapStorage pixmap; + + const SkImageInfo info = SkImageInfo::MakeN32(kFullSize, kFullSize, kOpaque_SkAlphaType); + pixmap.alloc(info); + pixmap.erase(SK_ColorGREEN); + + const SkIRect& subset = SkIRect::MakeXYWH(kPad, kPad, kSmallerSize, kSmallerSize); + + pixmap.erase(SK_ColorRED, subset); + + { + // The SkAutoPixmapStorage keeps hold of the memory + SkAutoTUnref<SkSpecialImage> img(SkSpecialImage::NewFromPixmap(nullptr, subset, pixmap, + nullptr, nullptr)); + test_image(img, reporter, true, false, kPad, kFullSize); + } + + { + // The image takes ownership of the memory + SkAutoTUnref<SkSpecialImage> img(SkSpecialImage::NewFromPixmap( + nullptr, subset, pixmap, + [] (void* addr, void*) -> void { sk_free(addr); }, + nullptr)); + pixmap.release(); + test_image(img, reporter, true, false, kPad, kFullSize); + } +} + + #if SK_SUPPORT_GPU DEF_GPUTEST_FOR_RENDERING_CONTEXTS(SpecialImage_Gpu, reporter, context) { SkBitmap bm = create_bm(); @@ -128,12 +187,26 @@ DEF_GPUTEST_FOR_RENDERING_CONTEXTS(SpecialImage_Gpu, reporter, context) { return; } + SkAutoTUnref<SkSpecialImage> fullSImg(SkSpecialImage::NewFromGpu( + nullptr, + SkIRect::MakeWH(kFullSize, kFullSize), + kNeedNewImageUniqueID_SpecialImage, + texture)); + const SkIRect& subset = SkIRect::MakeXYWH(kPad, kPad, kSmallerSize, kSmallerSize); - SkAutoTUnref<SkSpecialImage> img(SkSpecialImage::NewFromGpu(nullptr, subset, - kNeedNewImageUniqueID_SpecialImage, - texture)); - test_image(img, reporter, false, true); + { + SkAutoTUnref<SkSpecialImage> subSImg1(SkSpecialImage::NewFromGpu( + nullptr, subset, + kNeedNewImageUniqueID_SpecialImage, + texture)); + test_image(subSImg1, reporter, false, true, kPad, kFullSize); + } + + { + SkAutoTUnref<SkSpecialImage> subSImg2(fullSImg->extractSubset(subset)); + test_image(subSImg2, reporter, false, true, kPad, kFullSize); + } } #endif diff --git a/tests/TestingSpecialImageAccess.h b/tests/TestingSpecialImageAccess.h index cd9d77c7ff..8dd4e9bb50 100644 --- a/tests/TestingSpecialImageAccess.h +++ b/tests/TestingSpecialImageAccess.h @@ -15,7 +15,7 @@ public: } static bool PeekPixels(const SkSpecialImage* img, SkPixmap* pixmap) { - return img->testingOnlyPeekPixels(pixmap); + return img->peekPixels(pixmap); } static GrTexture* PeekTexture(const SkSpecialImage* img) { diff --git a/tests/TextureCompressionTest.cpp b/tests/TextureCompressionTest.cpp index 18afebeff2..09086605a5 100644 --- a/tests/TextureCompressionTest.cpp +++ b/tests/TextureCompressionTest.cpp @@ -5,6 +5,7 @@ * found in the LICENSE file. */ +#include "SkAutoPixmapStorage.h" #include "SkBitmap.h" #include "SkData.h" #include "SkEndian.h" |