Index: src/core/SkSpecialImage.cpp |
diff --git a/src/core/SkSpecialImage.cpp b/src/core/SkSpecialImage.cpp |
index 88d90b860253cb830cdad4595b546a7b09731906..86a0088791542201b7b1b433133a4a12954d8b0a 100644 |
--- a/src/core/SkSpecialImage.cpp |
+++ b/src/core/SkSpecialImage.cpp |
@@ -24,6 +24,8 @@ public: |
virtual GrTexture* onPeekTexture() const { return nullptr; } |
+ virtual bool onGetROPixels(SkBitmap*) const = 0; |
+ |
// Delete this entry point ASAP (see skbug.com/4965) |
virtual bool getBitmap(SkBitmap* result) const = 0; |
@@ -50,6 +52,10 @@ GrTexture* SkSpecialImage::peekTexture() const { |
return as_SIB(this)->onPeekTexture(); |
} |
+bool SkSpecialImage::getROPixels(SkBitmap* result) const { |
+ return as_SIB(this)->onGetROPixels(result); |
+} |
+ |
SkSpecialSurface* SkSpecialImage::newSurface(const SkImageInfo& info) const { |
return as_SIB(this)->onNewSurface(info); |
} |
@@ -135,6 +141,10 @@ public: |
return false; |
} |
+ bool onGetROPixels(SkBitmap* result) const override { |
+ return false; |
+ } |
+ |
SkSpecialSurface* onNewSurface(const SkImageInfo& info) const override { |
#if SK_SUPPORT_GPU |
GrTexture* texture = as_IB(fImage.get())->peekTexture(); |
@@ -156,6 +166,11 @@ private: |
#ifdef SK_DEBUG |
static bool rect_fits(const SkIRect& rect, int width, int height) { |
+ if (0 == width && 0 == height) { |
+ SkASSERT(0 == rect.fLeft && 0 == rect.fRight && 0 == rect.fTop && 0 == rect.fBottom); |
+ return true; |
+ } |
+ |
return rect.fLeft >= 0 && rect.fLeft < width && rect.fLeft < rect.fRight && |
rect.fRight >= 0 && rect.fRight <= width && |
rect.fTop >= 0 && rect.fTop < height && rect.fTop < rect.fBottom && |
@@ -178,7 +193,7 @@ public: |
SkSpecialImage_Raster(SkImageFilter::Proxy* proxy, const SkIRect& subset, const SkBitmap& bm) |
: INHERITED(proxy, subset, bm.getGenerationID()) |
, fBitmap(bm) { |
- if (bm.pixelRef()->isPreLocked()) { |
+ if (bm.pixelRef() && bm.pixelRef()->isPreLocked()) { |
// we only preemptively lock if there is no chance of triggering something expensive |
// like a lazy decode or imagegenerator. PreLocked means it is flat pixels already. |
fBitmap.lockPixels(); |
@@ -219,6 +234,11 @@ public: |
return true; |
} |
+ bool onGetROPixels(SkBitmap* result) const override { |
+ *result = fBitmap; |
+ return true; |
+ } |
+ |
SkSpecialSurface* onNewSurface(const SkImageInfo& info) const override { |
return SkSpecialSurface::NewRaster(this->proxy(), info, nullptr); |
} |
@@ -285,6 +305,25 @@ public: |
return true; |
} |
+ bool onGetROPixels(SkBitmap* result) const override { |
+ |
+ const SkImageInfo info = SkImageInfo::MakeN32(this->width(), |
+ this->height(), |
+ this->isOpaque() ? kOpaque_SkAlphaType |
+ : kPremul_SkAlphaType); |
+ if (!result->tryAllocPixels(info)) { |
+ return false; |
+ } |
+ |
+ if (!fTexture->readPixels(0, 0, result->width(), result->height(), kSkia8888_GrPixelConfig, |
+ result->getPixels(), result->rowBytes())) { |
+ return false; |
+ } |
+ |
+ result->pixelRef()->setImmutable(); |
+ return true; |
+ } |
+ |
SkSpecialSurface* onNewSurface(const SkImageInfo& info) const override { |
GrSurfaceDesc desc = GrImageInfoToSurfaceDesc(info); |
desc.fFlags = kRenderTarget_GrSurfaceFlag; |