Index: src/core/SkSpecialImage.cpp |
diff --git a/src/core/SkSpecialImage.cpp b/src/core/SkSpecialImage.cpp |
index a55fe650293e0216b8ddc4167e4864fdcfb7f55a..b17d5d4147d998d85016a1f2d50c6bbb63ac91e7 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; |