remove SkImage::applyFilter() -- unused, can always re-add later
BUG=skia: GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1573653002 Review URL: https://codereview.chromium.org/1573653002
This commit is contained in:
parent
77b6ba3b6e
commit
22471ed134
@ -87,113 +87,3 @@ private:
|
|||||||
typedef GM INHERITED;
|
typedef GM INHERITED;
|
||||||
};
|
};
|
||||||
DEF_GM( return new SpriteBitmapGM; )
|
DEF_GM( return new SpriteBitmapGM; )
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
#include "SkColorFilterImageFilter.h"
|
|
||||||
#include "SkModeColorFilter.h"
|
|
||||||
#include "SkMorphologyImageFilter.h"
|
|
||||||
#include "SkOffsetImageFilter.h"
|
|
||||||
|
|
||||||
static SkImage* make_image(SkCanvas* rootCanvas) {
|
|
||||||
SkImageInfo info = SkImageInfo::MakeN32Premul(100, 100);
|
|
||||||
SkAutoTUnref<SkSurface> surface(rootCanvas->newSurface(info));
|
|
||||||
if (!surface) {
|
|
||||||
surface.reset(SkSurface::NewRaster(info));
|
|
||||||
}
|
|
||||||
|
|
||||||
SkPaint paint;
|
|
||||||
paint.setAntiAlias(true);
|
|
||||||
paint.setColor(SK_ColorRED);
|
|
||||||
surface->getCanvas()->drawCircle(50, 50, 50, paint);
|
|
||||||
return surface->newImageSnapshot();
|
|
||||||
}
|
|
||||||
|
|
||||||
static void show_image(SkCanvas* canvas, SkImage* image, const SkIPoint& offset) {
|
|
||||||
SkScalar x = SkIntToScalar(offset.x());
|
|
||||||
SkScalar y = SkIntToScalar(offset.y());
|
|
||||||
|
|
||||||
SkPaint paint;
|
|
||||||
paint.setStyle(SkPaint::kStroke_Style);
|
|
||||||
|
|
||||||
SkRect r = SkRect::MakeIWH(image->width(), image->height());
|
|
||||||
r.offset(x, y);
|
|
||||||
// get on pixel-centers to make the hairline land on a numerical stable boundary
|
|
||||||
r.outset(SK_ScalarHalf, SK_ScalarHalf);
|
|
||||||
canvas->drawRect(r, paint);
|
|
||||||
|
|
||||||
canvas->drawImage(image, x, y, nullptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
typedef SkImageFilter* (*ImageFilterFactory)();
|
|
||||||
|
|
||||||
// +[]{...} did not work on windows (VS)
|
|
||||||
// (ImageFilterFactory)[]{...} did not work on linux (gcc)
|
|
||||||
// hence this cast function
|
|
||||||
template <typename T> ImageFilterFactory IFCCast(T arg) { return arg; }
|
|
||||||
|
|
||||||
// We expect that applying the filter will keep us in the same domain (raster or gpu)
|
|
||||||
static void check_same_domain(SkImage* a, SkImage* b) {
|
|
||||||
SkASSERT(a->isTextureBacked() == b->isTextureBacked());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Compare output of drawSprite and drawBitmap (esp. clipping and imagefilters)
|
|
||||||
*/
|
|
||||||
class ApplyFilterGM : public skiagm::GM {
|
|
||||||
public:
|
|
||||||
ApplyFilterGM() {}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
SkString onShortName() override {
|
|
||||||
return SkString("apply-filter");
|
|
||||||
}
|
|
||||||
|
|
||||||
SkISize onISize() override {
|
|
||||||
return SkISize::Make(780, 780);
|
|
||||||
}
|
|
||||||
|
|
||||||
void onDraw(SkCanvas* canvas) override {
|
|
||||||
SkAutoTUnref<SkImage> image0(make_image(canvas));
|
|
||||||
|
|
||||||
const ImageFilterFactory factories[] = {
|
|
||||||
IFCCast([]{ return SkBlurImageFilter::Create(8, 8); }),
|
|
||||||
IFCCast([]{ SkAutoTUnref<SkColorFilter> cf(SkModeColorFilter::Create(SK_ColorBLUE,
|
|
||||||
SkXfermode::kSrcIn_Mode));
|
|
||||||
return SkColorFilterImageFilter::Create(cf);
|
|
||||||
}),
|
|
||||||
IFCCast([]{ return SkDilateImageFilter::Create(8, 8); }),
|
|
||||||
IFCCast([]{ return SkErodeImageFilter::Create(8, 8); }),
|
|
||||||
IFCCast([]{ return SkOffsetImageFilter::Create(8, 8); }),
|
|
||||||
};
|
|
||||||
|
|
||||||
const SkScalar spacer = image0->width() * 3.0f / 2;
|
|
||||||
|
|
||||||
for (auto&& factory : factories) {
|
|
||||||
SkAutoTUnref<SkImageFilter> filter(factory());
|
|
||||||
|
|
||||||
SkIPoint offset1, offset2;
|
|
||||||
SkAutoTUnref<SkImage> image1(image0->applyFilter(filter, &offset1, true));
|
|
||||||
SkAutoTUnref<SkImage> image2(image0->applyFilter(filter, &offset2, false));
|
|
||||||
|
|
||||||
check_same_domain(image0, image1);
|
|
||||||
check_same_domain(image0, image2);
|
|
||||||
|
|
||||||
canvas->save();
|
|
||||||
canvas->translate(30, 30);
|
|
||||||
show_image(canvas, image0, SkIPoint::Make(0, 0)); // original
|
|
||||||
canvas->translate(spacer, 0);
|
|
||||||
show_image(canvas, image1, offset1); // snug
|
|
||||||
canvas->translate(spacer, 0);
|
|
||||||
show_image(canvas, image2, offset2); // not snug
|
|
||||||
|
|
||||||
canvas->restore();
|
|
||||||
|
|
||||||
canvas->translate(0, spacer);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
typedef GM INHERITED;
|
|
||||||
};
|
|
||||||
DEF_GM( return new ApplyFilterGM; )
|
|
||||||
|
@ -324,28 +324,6 @@ public:
|
|||||||
*/
|
*/
|
||||||
bool isLazyGenerated() const;
|
bool isLazyGenerated() const;
|
||||||
|
|
||||||
/**
|
|
||||||
* Apply the specified filter to this image, and return the result as a new image.
|
|
||||||
*
|
|
||||||
* if forceResultToOriginalSize is true, then the resulting image will be the same size as the
|
|
||||||
* src, regardless of the normal output of the filter.
|
|
||||||
*
|
|
||||||
* If offset is non-null, it is set to the relative offset needed to draw the resulting image
|
|
||||||
* in the same logical place as the original.
|
|
||||||
*
|
|
||||||
* e.g.
|
|
||||||
* If the filter makes the result larger by a margin of 4 the output would be:
|
|
||||||
* result->width() == this->width + 8
|
|
||||||
* result->height() == this->height + 8
|
|
||||||
* offset.x() == -4
|
|
||||||
* offset.y() == -4
|
|
||||||
*
|
|
||||||
* If the filter fails to create a resulting image, null is returned, and the offset parameter
|
|
||||||
* (if specified) will be undefined.
|
|
||||||
*/
|
|
||||||
SkImage* applyFilter(SkImageFilter* filter, SkIPoint* offset,
|
|
||||||
bool forceResultToOriginalSize) const;
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
SkImage(int width, int height, uint32_t uniqueID);
|
SkImage(int width, int height, uint32_t uniqueID);
|
||||||
|
|
||||||
|
@ -89,80 +89,6 @@ void SkImage::preroll(GrContext* ctx) const {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SkImage* SkImage::applyFilter(SkImageFilter* filter, SkIPoint* offset,
|
|
||||||
bool forceResultToOriginalSize) const {
|
|
||||||
if (!filter) {
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
SkIPoint offsetStorage;
|
|
||||||
if (!offset) {
|
|
||||||
offset = &offsetStorage;
|
|
||||||
}
|
|
||||||
return as_IB(this)->onApplyFilter(filter, offset, forceResultToOriginalSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
#include "SkImageFilter.h"
|
|
||||||
#include "SkBitmapDevice.h"
|
|
||||||
|
|
||||||
static SkIRect compute_fast_ibounds(SkImageFilter* filter, const SkIRect& srcBounds) {
|
|
||||||
SkRect fastBounds;
|
|
||||||
fastBounds.set(srcBounds);
|
|
||||||
filter->computeFastBounds(fastBounds, &fastBounds);
|
|
||||||
return fastBounds.roundOut();
|
|
||||||
}
|
|
||||||
|
|
||||||
class SkRasterImageFilterProxy : public SkImageFilter::Proxy {
|
|
||||||
public:
|
|
||||||
SkBaseDevice* createDevice(int width, int height) override {
|
|
||||||
return SkBitmapDevice::Create(SkImageInfo::MakeN32Premul(width, height));
|
|
||||||
}
|
|
||||||
|
|
||||||
bool filterImage(const SkImageFilter*, const SkBitmap&, const SkImageFilter::Context&,
|
|
||||||
SkBitmap*, SkIPoint*) override {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
SkImage* SkImage_Base::onApplyFilter(SkImageFilter* filter, SkIPoint* offsetResult,
|
|
||||||
bool forceResultToOriginalSize) const {
|
|
||||||
SkBitmap src;
|
|
||||||
if (!this->getROPixels(&src)) {
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
const SkIRect srcBounds = SkIRect::MakeWH(this->width(), this->height());
|
|
||||||
|
|
||||||
if (forceResultToOriginalSize) {
|
|
||||||
const SkIRect clipBounds = srcBounds;
|
|
||||||
SkRasterImageFilterProxy proxy;
|
|
||||||
SkImageFilter::Context ctx(SkMatrix::I(), clipBounds, SkImageFilter::Cache::Get(),
|
|
||||||
SkImageFilter::kExact_SizeConstraint);
|
|
||||||
|
|
||||||
SkBitmap dst;
|
|
||||||
if (filter->filterImage(&proxy, src, ctx, &dst, offsetResult)) {
|
|
||||||
dst.setImmutable();
|
|
||||||
return SkImage::NewFromBitmap(dst);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
const SkIRect dstR = compute_fast_ibounds(filter, srcBounds);
|
|
||||||
|
|
||||||
SkImageInfo info = SkImageInfo::MakeN32Premul(dstR.width(), dstR.height());
|
|
||||||
SkAutoTUnref<SkSurface> surface(this->onNewSurface(info));
|
|
||||||
|
|
||||||
SkPaint paint;
|
|
||||||
paint.setImageFilter(filter);
|
|
||||||
surface->getCanvas()->drawImage(this, SkIntToScalar(-dstR.x()), SkIntToScalar(-dstR.y()),
|
|
||||||
&paint);
|
|
||||||
|
|
||||||
offsetResult->set(dstR.x(), dstR.y());
|
|
||||||
return surface->newImageSnapshot();
|
|
||||||
}
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
SkShader* SkImage::newShader(SkShader::TileMode tileX,
|
SkShader* SkImage::newShader(SkShader::TileMode tileX,
|
||||||
|
@ -39,9 +39,6 @@ public:
|
|||||||
// but only inspect them (or encode them).
|
// but only inspect them (or encode them).
|
||||||
virtual bool getROPixels(SkBitmap*, CachingHint = kAllow_CachingHint) const = 0;
|
virtual bool getROPixels(SkBitmap*, CachingHint = kAllow_CachingHint) const = 0;
|
||||||
|
|
||||||
virtual SkImage* onApplyFilter(SkImageFilter*, SkIPoint* offset,
|
|
||||||
bool forceResultToOriginalSize) const;
|
|
||||||
|
|
||||||
virtual SkSurface* onNewSurface(const SkImageInfo& info) const {
|
virtual SkSurface* onNewSurface(const SkImageInfo& info) const {
|
||||||
return SkSurface::NewRaster(info);
|
return SkSurface::NewRaster(info);
|
||||||
}
|
}
|
||||||
|
@ -152,82 +152,6 @@ SkImage* SkImage_Gpu::onNewSubset(const SkIRect& subset) const {
|
|||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
class SkGpuImageFilterProxy : public SkImageFilter::Proxy {
|
|
||||||
GrContext* fCtx;
|
|
||||||
|
|
||||||
public:
|
|
||||||
SkGpuImageFilterProxy(GrContext* ctx) : fCtx(ctx) {}
|
|
||||||
|
|
||||||
SkBaseDevice* createDevice(int width, int height) override {
|
|
||||||
GrSurfaceDesc desc;
|
|
||||||
desc.fConfig = kSkia8888_GrPixelConfig;
|
|
||||||
desc.fFlags = kRenderTarget_GrSurfaceFlag;
|
|
||||||
desc.fWidth = width;
|
|
||||||
desc.fHeight = height;
|
|
||||||
desc.fSampleCnt = 0;
|
|
||||||
|
|
||||||
SkAutoTUnref<GrTexture> texture(fCtx->textureProvider()->createTexture(desc, true));
|
|
||||||
|
|
||||||
if (texture) {
|
|
||||||
SkSurfaceProps props(0, kUnknown_SkPixelGeometry);
|
|
||||||
return SkGpuDevice::Create(texture->asRenderTarget(), width, height, &props,
|
|
||||||
SkGpuDevice::kClear_InitContents);
|
|
||||||
} else {
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool filterImage(const SkImageFilter* filter, const SkBitmap& src,
|
|
||||||
const SkImageFilter::Context& ctx, SkBitmap* dst, SkIPoint* offset) override {
|
|
||||||
return filter->canFilterImageGPU() &&
|
|
||||||
filter->filterImageGPU(this, src, ctx, dst, offset);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
static SkIRect compute_fast_ibounds(SkImageFilter* filter, const SkIRect& srcBounds) {
|
|
||||||
SkRect fastBounds;
|
|
||||||
fastBounds.set(srcBounds);
|
|
||||||
filter->computeFastBounds(fastBounds, &fastBounds);
|
|
||||||
return fastBounds.roundOut();
|
|
||||||
}
|
|
||||||
|
|
||||||
SkImage* SkImage_Gpu::onApplyFilter(SkImageFilter* filter, SkIPoint* offsetResult,
|
|
||||||
bool forceResultToOriginalSize) const {
|
|
||||||
const SkIRect srcBounds = SkIRect::MakeWH(this->width(), this->height());
|
|
||||||
|
|
||||||
if (forceResultToOriginalSize) {
|
|
||||||
SkBitmap src;
|
|
||||||
GrWrapTextureInBitmap(fTexture, this->width(), this->height(), this->isOpaque(), &src);
|
|
||||||
|
|
||||||
const SkIRect clipBounds = srcBounds;
|
|
||||||
SkGpuImageFilterProxy proxy(fTexture->getContext());
|
|
||||||
SkAutoTUnref<SkImageFilter::Cache> cache(SkGpuDevice::NewImageFilterCache());
|
|
||||||
SkImageFilter::Context ctx(SkMatrix::I(), clipBounds, cache, SkImageFilter::kExact_SizeConstraint);
|
|
||||||
|
|
||||||
SkBitmap dst;
|
|
||||||
if (!filter->filterImage(&proxy, src, ctx, &dst, offsetResult)) {
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
return new SkImage_Gpu(dst.width(), dst.height(), kNeedNewImageUniqueID, dst.alphaType(),
|
|
||||||
dst.getTexture(), SkSurface::kNo_Budgeted);
|
|
||||||
}
|
|
||||||
|
|
||||||
const SkIRect dstR = compute_fast_ibounds(filter, srcBounds);
|
|
||||||
|
|
||||||
SkImageInfo info = SkImageInfo::MakeN32Premul(dstR.width(), dstR.height());
|
|
||||||
SkAutoTUnref<SkSurface> surface(this->onNewSurface(info));
|
|
||||||
|
|
||||||
SkPaint paint;
|
|
||||||
paint.setImageFilter(filter);
|
|
||||||
surface->getCanvas()->drawImage(this, SkIntToScalar(-dstR.x()), SkIntToScalar(-dstR.y()),
|
|
||||||
&paint);
|
|
||||||
|
|
||||||
offsetResult->set(dstR.x(), dstR.y());
|
|
||||||
return surface->newImageSnapshot();
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
static SkImage* new_wrapped_texture_common(GrContext* ctx, const GrBackendTextureDesc& desc,
|
static SkImage* new_wrapped_texture_common(GrContext* ctx, const GrBackendTextureDesc& desc,
|
||||||
SkAlphaType at, GrWrapOwnership ownership,
|
SkAlphaType at, GrWrapOwnership ownership,
|
||||||
SkImage::TextureReleaseProc releaseProc,
|
SkImage::TextureReleaseProc releaseProc,
|
||||||
|
@ -43,8 +43,6 @@ public:
|
|||||||
bool isOpaque() const override;
|
bool isOpaque() const override;
|
||||||
bool onReadPixels(const SkImageInfo&, void* dstPixels, size_t dstRowBytes,
|
bool onReadPixels(const SkImageInfo&, void* dstPixels, size_t dstRowBytes,
|
||||||
int srcX, int srcY, CachingHint) const override;
|
int srcX, int srcY, CachingHint) const override;
|
||||||
SkImage* onApplyFilter(SkImageFilter*, SkIPoint* offset,
|
|
||||||
bool forceResultToOriginalSize) const override;
|
|
||||||
|
|
||||||
SkSurface* onNewSurface(const SkImageInfo& info) const override {
|
SkSurface* onNewSurface(const SkImageInfo& info) const override {
|
||||||
return SkSurface::NewRenderTarget(fTexture->getContext(), SkSurface::kNo_Budgeted, info);
|
return SkSurface::NewRenderTarget(fTexture->getContext(), SkSurface::kNo_Budgeted, info);
|
||||||
|
Loading…
Reference in New Issue
Block a user