Index: src/core/SkSpecialImage.cpp |
diff --git a/src/core/SkSpecialImage.cpp b/src/core/SkSpecialImage.cpp |
index 4fed2ac24a0afdcd866e5234de79aa31f8fbdc45..50117b2e83556e64a1fe70dd2e218c8b1532a3ea 100644 |
--- a/src/core/SkSpecialImage.cpp |
+++ b/src/core/SkSpecialImage.cpp |
@@ -12,7 +12,9 @@ |
/////////////////////////////////////////////////////////////////////////////// |
class SkSpecialImage_Base : public SkSpecialImage { |
public: |
- SkSpecialImage_Base(const SkIRect& subset) : INHERITED(subset) { } |
+ SkSpecialImage_Base(SkImageFilter::Proxy* proxy, const SkIRect& subset, uint32_t uniqueID) |
+ : INHERITED(proxy, subset, uniqueID) { |
+ } |
virtual ~SkSpecialImage_Base() { } |
virtual void onDraw(SkCanvas*, SkScalar x, SkScalar y, const SkPaint*) const = 0; |
@@ -21,6 +23,9 @@ public: |
virtual GrTexture* onPeekTexture() const { return nullptr; } |
+ // Delete this entry point ASAP (see skbug.com/4965) |
+ virtual bool getBitmap(SkBitmap* result) const = 0; |
+ |
virtual SkSpecialSurface* onNewSurface(const SkImageInfo& info) const { return nullptr; } |
private: |
@@ -48,22 +53,70 @@ SkSpecialSurface* SkSpecialImage::newSurface(const SkImageInfo& info) const { |
return as_IB(this)->onNewSurface(info); |
} |
+#if SK_SUPPORT_GPU |
+#include "SkGr.h" |
+#include "SkGrPixelRef.h" |
+#endif |
+ |
+SkSpecialImage* SkSpecialImage::internal_fromBM(SkImageFilter::Proxy* proxy, |
+ const SkBitmap& src) { |
+ // Need to test offset case! (see skbug.com/4967) |
+ if (src.getTexture()) { |
+ return SkSpecialImage::NewFromGpu(proxy, |
+ src.bounds(), |
+ src.getGenerationID(), |
+ src.getTexture()); |
+ } |
+ |
+ return SkSpecialImage::NewFromRaster(proxy, src.bounds(), src); |
+} |
+ |
+bool SkSpecialImage::internal_getBM(SkBitmap* result) { |
+ const SkSpecialImage_Base* ib = as_IB(this); |
+ |
+ // TODO: need to test offset case! (see skbug.com/4967) |
+ return ib->getBitmap(result); |
+} |
+ |
+SkImageFilter::Proxy* SkSpecialImage::internal_getProxy() { |
+ SkASSERT(fProxy); |
+ return fProxy; |
+} |
+ |
/////////////////////////////////////////////////////////////////////////////// |
#include "SkImage.h" |
#if SK_SUPPORT_GPU |
-#include "SkGr.h" |
#include "SkGrPriv.h" |
#endif |
class SkSpecialImage_Image : public SkSpecialImage_Base { |
public: |
- SkSpecialImage_Image(const SkIRect& subset, const SkImage* image) |
- : INHERITED(subset) |
+ SkSpecialImage_Image(SkImageFilter::Proxy* proxy, const SkIRect& subset, const SkImage* image) |
+ : INHERITED(proxy, subset, image->uniqueID()) |
, fImage(SkRef(image)) { |
} |
~SkSpecialImage_Image() override { } |
+ bool isOpaque() const override { return fImage->isOpaque(); } |
+ |
+ size_t getSize() const override { |
+#if SK_SUPPORT_GPU |
+ if (fImage->getTexture()) { |
+ return fImage->getTexture()->gpuMemorySize(); |
+ } else |
+#endif |
+ { |
+ SkImageInfo info; |
+ size_t rowBytes; |
+ |
+ if (fImage->peekPixels(&info, &rowBytes)) { |
+ return info.height() * rowBytes; |
+ } |
+ } |
+ return 0; |
+ } |
+ |
void onDraw(SkCanvas* canvas, SkScalar x, SkScalar y, const SkPaint* paint) const override { |
SkRect dst = SkRect::MakeXYWH(x, y, this->subset().width(), this->subset().height()); |
@@ -77,6 +130,10 @@ public: |
GrTexture* onPeekTexture() const override { return fImage->getTexture(); } |
+ bool getBitmap(SkBitmap* result) const override { |
+ return false; |
+ } |
+ |
SkSpecialSurface* onNewSurface(const SkImageInfo& info) const override { |
#if SK_SUPPORT_GPU |
GrTexture* texture = fImage->getTexture(); |
@@ -84,10 +141,10 @@ public: |
GrSurfaceDesc desc = GrImageInfoToSurfaceDesc(info); |
desc.fFlags = kRenderTarget_GrSurfaceFlag; |
- return SkSpecialSurface::NewRenderTarget(texture->getContext(), desc); |
+ return SkSpecialSurface::NewRenderTarget(this->proxy(), texture->getContext(), desc); |
} |
#endif |
- return SkSpecialSurface::NewRaster(info, nullptr); |
+ return SkSpecialSurface::NewRaster(this->proxy(), info, nullptr); |
} |
private: |
@@ -107,7 +164,7 @@ static bool rect_fits(const SkIRect& rect, int width, int height) { |
SkSpecialImage* SkSpecialImage::NewFromImage(const SkIRect& subset, const SkImage* image) { |
SkASSERT(rect_fits(subset, image->width(), image->height())); |
- return new SkSpecialImage_Image(subset, image); |
+ return new SkSpecialImage_Image(nullptr, subset, image); |
} |
/////////////////////////////////////////////////////////////////////////////// |
@@ -117,8 +174,8 @@ SkSpecialImage* SkSpecialImage::NewFromImage(const SkIRect& subset, const SkImag |
class SkSpecialImage_Raster : public SkSpecialImage_Base { |
public: |
- SkSpecialImage_Raster(const SkIRect& subset, const SkBitmap& bm) |
- : INHERITED(subset) |
+ SkSpecialImage_Raster(SkImageFilter::Proxy* proxy, const SkIRect& subset, const SkBitmap& bm) |
+ : INHERITED(proxy, subset, bm.getGenerationID()) |
, fBitmap(bm) { |
if (bm.pixelRef()->isPreLocked()) { |
// we only preemptively lock if there is no chance of triggering something expensive |
@@ -129,6 +186,10 @@ public: |
~SkSpecialImage_Raster() override { } |
+ bool isOpaque() const override { return fBitmap.isOpaque(); } |
+ |
+ size_t getSize() const override { return fBitmap.getSize(); } |
+ |
void onDraw(SkCanvas* canvas, SkScalar x, SkScalar y, const SkPaint* paint) const override { |
SkRect dst = SkRect::MakeXYWH(x, y, |
this->subset().width(), this->subset().height()); |
@@ -152,8 +213,13 @@ public: |
return false; |
} |
+ bool getBitmap(SkBitmap* result) const override { |
+ *result = fBitmap; |
+ return true; |
+ } |
+ |
SkSpecialSurface* onNewSurface(const SkImageInfo& info) const override { |
- return SkSpecialSurface::NewRaster(info, nullptr); |
+ return SkSpecialSurface::NewRaster(this->proxy(), info, nullptr); |
} |
private: |
@@ -162,10 +228,12 @@ private: |
typedef SkSpecialImage_Base INHERITED; |
}; |
-SkSpecialImage* SkSpecialImage::NewFromRaster(const SkIRect& subset, const SkBitmap& bm) { |
+SkSpecialImage* SkSpecialImage::NewFromRaster(SkImageFilter::Proxy* proxy, |
+ const SkIRect& subset, |
+ const SkBitmap& bm) { |
SkASSERT(nullptr == bm.getTexture()); |
SkASSERT(rect_fits(subset, bm.width(), bm.height())); |
- return new SkSpecialImage_Raster(subset, bm); |
+ return new SkSpecialImage_Raster(proxy, subset, bm); |
} |
#if SK_SUPPORT_GPU |
@@ -173,23 +241,30 @@ SkSpecialImage* SkSpecialImage::NewFromRaster(const SkIRect& subset, const SkBit |
#include "GrTexture.h" |
class SkSpecialImage_Gpu : public SkSpecialImage_Base { |
-public: |
- SkSpecialImage_Gpu(const SkIRect& subset, GrTexture* tex) |
- : INHERITED(subset) |
- , fTexture(SkRef(tex)) { |
+public: |
+ SkSpecialImage_Gpu(SkImageFilter::Proxy* proxy, const SkIRect& subset, |
+ uint32_t uniqueID, GrTexture* tex, SkAlphaType at) |
+ : INHERITED(proxy, subset, uniqueID) |
+ , fTexture(SkRef(tex)) |
+ , fAlphaType(at) { |
} |
~SkSpecialImage_Gpu() override { } |
+ bool isOpaque() const override { |
+ return GrPixelConfigIsOpaque(fTexture->config()) || fAlphaType == kOpaque_SkAlphaType; |
+ } |
+ |
+ size_t getSize() const override { return fTexture->gpuMemorySize(); } |
+ |
void onDraw(SkCanvas* canvas, SkScalar x, SkScalar y, const SkPaint* paint) const override { |
SkRect dst = SkRect::MakeXYWH(x, y, |
this->subset().width(), this->subset().height()); |
SkBitmap bm; |
- static const bool kUnknownOpacity = false; |
GrWrapTextureInBitmap(fTexture, |
- fTexture->width(), fTexture->height(), kUnknownOpacity, &bm); |
+ fTexture->width(), fTexture->height(), this->isOpaque(), &bm); |
canvas->drawBitmapRect(bm, this->subset(), |
dst, paint, SkCanvas::kStrict_SrcRectConstraint); |
@@ -197,27 +272,48 @@ public: |
GrTexture* onPeekTexture() const override { return fTexture; } |
+ bool getBitmap(SkBitmap* result) const override { |
+ const SkImageInfo info = GrMakeInfoFromTexture(fTexture, |
+ this->width(), this->height(), |
+ this->isOpaque()); |
+ if (!result->setInfo(info)) { |
+ return false; |
+ } |
+ |
+ result->setPixelRef(new SkGrPixelRef(info, fTexture))->unref(); |
+ return true; |
+ } |
+ |
SkSpecialSurface* onNewSurface(const SkImageInfo& info) const override { |
GrSurfaceDesc desc = GrImageInfoToSurfaceDesc(info); |
desc.fFlags = kRenderTarget_GrSurfaceFlag; |
- return SkSpecialSurface::NewRenderTarget(fTexture->getContext(), desc); |
+ return SkSpecialSurface::NewRenderTarget(this->proxy(), fTexture->getContext(), desc); |
} |
private: |
SkAutoTUnref<GrTexture> fTexture; |
+ const SkAlphaType fAlphaType; |
typedef SkSpecialImage_Base INHERITED; |
}; |
-SkSpecialImage* SkSpecialImage::NewFromGpu(const SkIRect& subset, GrTexture* tex) { |
+SkSpecialImage* SkSpecialImage::NewFromGpu(SkImageFilter::Proxy* proxy, |
+ const SkIRect& subset, |
+ uint32_t uniqueID, |
+ GrTexture* tex, |
+ SkAlphaType at) { |
SkASSERT(rect_fits(subset, tex->width(), tex->height())); |
- return new SkSpecialImage_Gpu(subset, tex); |
+ return new SkSpecialImage_Gpu(proxy, subset, uniqueID, tex, at); |
} |
#else |
-SkSpecialImage* SkSpecialImage::NewFromGpu(const SkIRect& subset, GrTexture* tex) { |
+SkSpecialImage* SkSpecialImage::NewFromGpu(SkImageFilter::Proxy* proxy, |
+ const SkIRect& subset, |
+ uint32_t uniqueID, |
+ GrTexture* tex, |
+ SkAlphaType at) { |
return nullptr; |
} |