Index: src/core/SkSpecialImage.cpp |
diff --git a/src/core/SkSpecialImage.cpp b/src/core/SkSpecialImage.cpp |
index 88d90b860253cb830cdad4595b546a7b09731906..0bbe50a688607ac9415b23582d29d3b4a3b93578 100644 |
--- a/src/core/SkSpecialImage.cpp |
+++ b/src/core/SkSpecialImage.cpp |
@@ -20,10 +20,12 @@ public: |
virtual void onDraw(SkCanvas*, SkScalar x, SkScalar y, const SkPaint*) const = 0; |
- virtual bool onPeekPixels(SkPixmap*) const { return false; } |
+ virtual bool testingOnlyOnPeekPixels(SkPixmap*) const { return false; } |
virtual GrTexture* onPeekTexture() const { return nullptr; } |
+ virtual bool testingOnlyOnGetROPixels(SkBitmap*) const = 0; |
+ |
// Delete this entry point ASAP (see skbug.com/4965) |
virtual bool getBitmap(SkBitmap* result) const = 0; |
@@ -42,14 +44,18 @@ void SkSpecialImage::draw(SkCanvas* canvas, SkScalar x, SkScalar y, const SkPain |
return as_SIB(this)->onDraw(canvas, x, y, paint); |
} |
-bool SkSpecialImage::peekPixels(SkPixmap* pixmap) const { |
- return as_SIB(this)->onPeekPixels(pixmap); |
+bool SkSpecialImage::testingOnlyPeekPixels(SkPixmap* pixmap) const { |
+ return as_SIB(this)->testingOnlyOnPeekPixels(pixmap); |
} |
GrTexture* SkSpecialImage::peekTexture() const { |
return as_SIB(this)->onPeekTexture(); |
} |
+bool SkSpecialImage::testingOnlyGetROPixels(SkBitmap* result) const { |
+ return as_SIB(this)->testingOnlyOnGetROPixels(result); |
+} |
+ |
SkSpecialSurface* SkSpecialImage::newSurface(const SkImageInfo& info) const { |
return as_SIB(this)->onNewSurface(info); |
} |
@@ -125,7 +131,7 @@ public: |
dst, paint, SkCanvas::kStrict_SrcRectConstraint); |
} |
- bool onPeekPixels(SkPixmap* pixmap) const override { |
+ bool testingOnlyOnPeekPixels(SkPixmap* pixmap) const override { |
return fImage->peekPixels(pixmap); |
} |
@@ -135,6 +141,10 @@ public: |
return false; |
} |
+ bool testingOnlyOnGetROPixels(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(); |
@@ -199,7 +214,7 @@ public: |
dst, paint, SkCanvas::kStrict_SrcRectConstraint); |
} |
- bool onPeekPixels(SkPixmap* pixmap) const override { |
+ bool testingOnlyOnPeekPixels(SkPixmap* pixmap) const override { |
const SkImageInfo info = fBitmap.info(); |
if ((kUnknown_SkColorType == info.colorType()) || !fBitmap.getPixels()) { |
return false; |
@@ -219,6 +234,11 @@ public: |
return true; |
} |
+ bool testingOnlyOnGetROPixels(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 testingOnlyOnGetROPixels(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; |