| 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;
|
| }
|
|
|
|
|