Switch SkTileImageFilter over to new onFilterImage interface
This relies on: https://codereview.chromium.org/1816223002 (Update SkSpecialImage to be able to create tight SkImages and SkSurfaces)
GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1810693003
Review URL: https://codereview.chromium.org/1810693003
diff --git a/include/effects/SkTileImageFilter.h b/include/effects/SkTileImageFilter.h
index ad334a3..1fccac6 100644
--- a/include/effects/SkTileImageFilter.h
+++ b/include/effects/SkTileImageFilter.h
@@ -11,8 +11,6 @@
#include "SkImageFilter.h"
class SK_API SkTileImageFilter : public SkImageFilter {
- typedef SkImageFilter INHERITED;
-
public:
/** Create a tile image filter
@param src Defines the pixels to tile
@@ -21,8 +19,6 @@
*/
static SkImageFilter* Create(const SkRect& src, const SkRect& dst, SkImageFilter* input);
- bool onFilterImageDeprecated(Proxy* proxy, const SkBitmap& src, const Context& ctx,
- SkBitmap* dst, SkIPoint* offset) const override;
SkIRect onFilterBounds(const SkIRect& src, const SkMatrix&, MapDirection) const override;
SkIRect onFilterNodeBounds(const SkIRect&, const SkMatrix&, MapDirection) const override;
SkRect computeFastBounds(const SkRect& src) const override;
@@ -33,12 +29,17 @@
protected:
void flatten(SkWriteBuffer& buffer) const override;
+ sk_sp<SkSpecialImage> onFilterImage(SkSpecialImage* source, const Context&,
+ SkIPoint* offset) const override;
+
private:
SkTileImageFilter(const SkRect& srcRect, const SkRect& dstRect, SkImageFilter* input)
: INHERITED(1, &input, NULL), fSrcRect(srcRect), fDstRect(dstRect) {}
SkRect fSrcRect;
SkRect fDstRect;
+
+ typedef SkImageFilter INHERITED;
};
#endif
diff --git a/src/effects/SkTileImageFilter.cpp b/src/effects/SkTileImageFilter.cpp
index 0ff19b2..9711eed 100644
--- a/src/effects/SkTileImageFilter.cpp
+++ b/src/effects/SkTileImageFilter.cpp
@@ -6,16 +6,19 @@
*/
#include "SkTileImageFilter.h"
-#include "SkBitmap.h"
+
#include "SkCanvas.h"
-#include "SkDevice.h"
-#include "SkOffsetImageFilter.h"
-#include "SkReadBuffer.h"
-#include "SkWriteBuffer.h"
+#include "SkImage.h"
#include "SkMatrix.h"
+#include "SkOffsetImageFilter.h"
#include "SkPaint.h"
+#include "SkReadBuffer.h"
#include "SkShader.h"
+#include "SkSpecialImage.h"
+#include "SkSpecialSurface.h"
+#include "SkSurface.h"
#include "SkValidationUtils.h"
+#include "SkWriteBuffer.h"
SkImageFilter* SkTileImageFilter::Create(const SkRect& srcRect, const SkRect& dstRect,
SkImageFilter* input) {
@@ -36,75 +39,87 @@
return new SkTileImageFilter(srcRect, dstRect, input);
}
-bool SkTileImageFilter::onFilterImageDeprecated(Proxy* proxy, const SkBitmap& src,
- const Context& ctx,
- SkBitmap* dst, SkIPoint* offset) const {
- SkBitmap source = src;
- SkIPoint srcOffset = SkIPoint::Make(0, 0);
- if (!this->filterInputDeprecated(0, proxy, src, ctx, &source, &srcOffset)) {
- return false;
+sk_sp<SkSpecialImage> SkTileImageFilter::onFilterImage(SkSpecialImage* source,
+ const Context& ctx,
+ SkIPoint* offset) const {
+ SkIPoint inputOffset = SkIPoint::Make(0, 0);
+ sk_sp<SkSpecialImage> input(this->filterInput(0, source, ctx, &inputOffset));
+ if (!input) {
+ return nullptr;
}
SkRect dstRect;
ctx.ctm().mapRect(&dstRect, fDstRect);
if (!dstRect.intersect(SkRect::Make(ctx.clipBounds()))) {
- offset->fX = offset->fY = 0;
- return true;
+ return nullptr;
}
+
const SkIRect dstIRect = dstRect.roundOut();
- int w = dstIRect.width();
- int h = dstIRect.height();
- if (!fSrcRect.width() || !fSrcRect.height() || !w || !h) {
- return false;
+ int dstWidth = dstIRect.width();
+ int dstHeight = dstIRect.height();
+ if (!fSrcRect.width() || !fSrcRect.height() || !dstWidth || !dstHeight) {
+ return nullptr;
}
SkRect srcRect;
ctx.ctm().mapRect(&srcRect, fSrcRect);
SkIRect srcIRect;
srcRect.roundOut(&srcIRect);
- srcIRect.offset(-srcOffset);
- SkBitmap subset;
- SkIRect srcBounds;
- source.getBounds(&srcBounds);
+ srcIRect.offset(-inputOffset);
+ const SkIRect inputBounds = SkIRect::MakeWH(input->width(), input->height());
- if (!SkIRect::Intersects(srcIRect, srcBounds)) {
- offset->fX = offset->fY = 0;
- return true;
+ if (!SkIRect::Intersects(srcIRect, inputBounds)) {
+ return nullptr;
}
- if (srcBounds.contains(srcIRect)) {
- if (!source.extractSubset(&subset, srcIRect)) {
- return false;
+
+ // We create an SkImage here b.c. it needs to be a tight fit for the tiling
+ sk_sp<SkImage> subset;
+ if (inputBounds.contains(srcIRect)) {
+ subset = input->makeTightSubset(srcIRect);
+ if (!subset) {
+ return nullptr;
}
} else {
- SkAutoTUnref<SkBaseDevice> device(proxy->createDevice(srcIRect.width(),
- srcIRect.height(),
- kPossible_TileUsage));
- if (!device) {
- return false;
+ const SkImageInfo info = SkImageInfo::MakeN32(srcIRect.width(), srcIRect.height(),
+ kPremul_SkAlphaType);
+ sk_sp<SkSurface> surf(input->makeTightSurface(info));
+ if (!surf) {
+ return nullptr;
}
- SkCanvas canvas(device);
- canvas.drawBitmap(source, SkIntToScalar(srcOffset.x()),
- SkIntToScalar(srcOffset.y()));
- subset = device->accessBitmap(false);
- }
- SkASSERT(subset.width() == srcIRect.width());
- SkASSERT(subset.height() == srcIRect.height());
- SkAutoTUnref<SkBaseDevice> device(proxy->createDevice(w, h));
- if (nullptr == device.get()) {
- return false;
+ SkCanvas* canvas = surf->getCanvas();
+ SkASSERT(canvas);
+
+ SkPaint paint;
+ paint.setXfermodeMode(SkXfermode::kSrc_Mode);
+
+ input->draw(canvas,
+ SkIntToScalar(inputOffset.x()), SkIntToScalar(inputOffset.y()),
+ &paint);
+
+ subset = surf->makeImageSnapshot();
}
- SkCanvas canvas(device);
+ SkASSERT(subset->width() == srcIRect.width());
+ SkASSERT(subset->height() == srcIRect.height());
+
+ const SkImageInfo info = SkImageInfo::MakeN32(dstWidth, dstHeight, kPremul_SkAlphaType);
+
+ sk_sp<SkSpecialSurface> surf(source->makeSurface(info));
+ if (!surf) {
+ return nullptr;
+ }
+
+ SkCanvas* canvas = surf->getCanvas();
+ SkASSERT(canvas);
+
SkPaint paint;
paint.setXfermodeMode(SkXfermode::kSrc_Mode);
- paint.setShader(SkShader::MakeBitmapShader(subset, SkShader::kRepeat_TileMode,
- SkShader::kRepeat_TileMode));
- canvas.translate(-dstRect.fLeft, -dstRect.fTop);
- canvas.drawRect(dstRect, paint);
- *dst = device->accessBitmap(false);
+ paint.setShader(subset->makeShader(SkShader::kRepeat_TileMode, SkShader::kRepeat_TileMode));
+ canvas->translate(-dstRect.fLeft, -dstRect.fTop);
+ canvas->drawRect(dstRect, paint);
offset->fX = dstIRect.fLeft;
offset->fY = dstIRect.fTop;
- return true;
+ return surf->makeImageSnapshot();
}
SkIRect SkTileImageFilter::onFilterNodeBounds(const SkIRect& src, const SkMatrix& ctm,