Swap over to using SkImageFilter::filterImage instead of filterImageDeprecated
This CL relies on https://codereview.chromium.org/1757983002/ (Add SkSpecialImage-based methods to SkImageFilter) GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1762013002 TBR=bsalomon@google.com Review URL: https://codereview.chromium.org/1762013002
This commit is contained in:
parent
19de504eae
commit
4418dbac33
@ -137,20 +137,19 @@ public:
|
||||
|
||||
/**
|
||||
* Request a new (result) image to be created from the src image.
|
||||
* If the src has no pixels (isNull()) then the request just wants to
|
||||
* receive the config and width/height of the result.
|
||||
*
|
||||
* The matrix is the current matrix on the canvas.
|
||||
* The context contains the environment in which the filter is occurring.
|
||||
* It includes the clip bounds, CTM and cache.
|
||||
*
|
||||
* Offset is the amount to translate the resulting image relative to the
|
||||
* src when it is drawn. This is an out-param.
|
||||
*
|
||||
* If the result image cannot be created, return false, in which case both
|
||||
* the result and offset parameters will be ignored by the caller.
|
||||
* If the result image cannot be created, return null, in which case
|
||||
* the offset parameters will be ignored by the caller.
|
||||
*
|
||||
* TODO: Right now the imagefilters sometimes return empty result bitmaps/
|
||||
* specialimages. That doesn't seem quite right.
|
||||
*/
|
||||
bool filterImageDeprecated(Proxy*, const SkBitmap& src, const Context&,
|
||||
SkBitmap* result, SkIPoint* offset) const;
|
||||
|
||||
SkSpecialImage* filterImage(SkSpecialImage* src, const Context&, SkIPoint* offset) const;
|
||||
|
||||
enum MapDirection {
|
||||
@ -460,6 +459,9 @@ private:
|
||||
friend class SkGraphics;
|
||||
static void PurgeCache();
|
||||
|
||||
bool filterImageDeprecated(Proxy*, const SkBitmap& src, const Context&,
|
||||
SkBitmap* result, SkIPoint* offset) const;
|
||||
|
||||
bool usesSrcInput() const { return fUsesSrcInput; }
|
||||
|
||||
typedef SkFlattenable INHERITED;
|
||||
|
@ -28,6 +28,7 @@
|
||||
#include "SkReadPixelsRec.h"
|
||||
#include "SkRRect.h"
|
||||
#include "SkSmallAllocator.h"
|
||||
#include "SkSpecialImage.h"
|
||||
#include "SkSurface_Base.h"
|
||||
#include "SkTextBlob.h"
|
||||
#include "SkTextFormatParams.h"
|
||||
@ -1392,19 +1393,29 @@ void SkCanvas::internalDrawDevice(SkBaseDevice* srcDev, int x, int y,
|
||||
SkIPoint pos = { x - iter.getX(), y - iter.getY() };
|
||||
if (filter && !dstDev->canHandleImageFilter(filter)) {
|
||||
SkImageFilter::DeviceProxy proxy(dstDev);
|
||||
SkBitmap dst;
|
||||
SkIPoint offset = SkIPoint::Make(0, 0);
|
||||
const SkBitmap& src = srcDev->accessBitmap(false);
|
||||
const SkBitmap& srcBM = srcDev->accessBitmap(false);
|
||||
SkMatrix matrix = *iter.fMatrix;
|
||||
matrix.postTranslate(SkIntToScalar(-pos.x()), SkIntToScalar(-pos.y()));
|
||||
SkIRect clipBounds = iter.fClip->getBounds().makeOffset(-pos.x(), -pos.y());
|
||||
const SkIRect clipBounds = iter.fClip->getBounds().makeOffset(-pos.x(), -pos.y());
|
||||
SkAutoTUnref<SkImageFilter::Cache> cache(dstDev->getImageFilterCache());
|
||||
SkImageFilter::Context ctx(matrix, clipBounds, cache.get());
|
||||
if (filter->filterImageDeprecated(&proxy, src, ctx, &dst, &offset)) {
|
||||
|
||||
SkAutoTUnref<SkSpecialImage> srcImg(SkSpecialImage::internal_fromBM(&proxy, srcBM));
|
||||
if (!srcImg) {
|
||||
continue; // something disastrous happened
|
||||
}
|
||||
|
||||
SkAutoTUnref<SkSpecialImage> resultImg(filter->filterImage(srcImg, ctx, &offset));
|
||||
if (resultImg) {
|
||||
SkPaint tmpUnfiltered(*paint);
|
||||
tmpUnfiltered.setImageFilter(nullptr);
|
||||
dstDev->drawSprite(iter, dst, pos.x() + offset.x(), pos.y() + offset.y(),
|
||||
tmpUnfiltered);
|
||||
SkBitmap resultBM;
|
||||
if (resultImg->internal_getBM(&resultBM)) {
|
||||
// TODO: add drawSprite(SkSpecialImage) to SkDevice? (see skbug.com/5073)
|
||||
dstDev->drawSprite(iter, resultBM, pos.x() + offset.x(), pos.y() + offset.y(),
|
||||
tmpUnfiltered);
|
||||
}
|
||||
}
|
||||
} else if (deviceIsBitmapDevice) {
|
||||
const SkBitmap& src = static_cast<SkBitmapDevice*>(srcDev)->fBitmap;
|
||||
|
@ -17,6 +17,7 @@
|
||||
#include "SkRasterClip.h"
|
||||
#include "SkRSXform.h"
|
||||
#include "SkShader.h"
|
||||
#include "SkSpecialImage.h"
|
||||
#include "SkTextBlobRunIterator.h"
|
||||
#include "SkTextToPathIter.h"
|
||||
|
||||
@ -408,17 +409,27 @@ void SkBaseDevice::drawBitmapAsSprite(const SkDraw& draw, const SkBitmap& bitmap
|
||||
SkImageFilter* filter = paint.getImageFilter();
|
||||
if (filter && !this->canHandleImageFilter(filter)) {
|
||||
SkImageFilter::DeviceProxy proxy(this);
|
||||
SkBitmap dst;
|
||||
SkIPoint offset = SkIPoint::Make(0, 0);
|
||||
SkMatrix matrix = *draw.fMatrix;
|
||||
matrix.postTranslate(SkIntToScalar(-x), SkIntToScalar(-y));
|
||||
const SkIRect clipBounds = draw.fClip->getBounds().makeOffset(-x, -y);
|
||||
SkAutoTUnref<SkImageFilter::Cache> cache(this->getImageFilterCache());
|
||||
SkImageFilter::Context ctx(matrix, clipBounds, cache.get());
|
||||
if (filter->filterImageDeprecated(&proxy, bitmap, ctx, &dst, &offset)) {
|
||||
|
||||
SkAutoTUnref<SkSpecialImage> srcImg(SkSpecialImage::internal_fromBM(&proxy, bitmap));
|
||||
if (!srcImg) {
|
||||
return; // something disastrous happened
|
||||
}
|
||||
|
||||
SkAutoTUnref<SkSpecialImage> resultImg(filter->filterImage(srcImg, ctx, &offset));
|
||||
if (resultImg) {
|
||||
SkPaint tmpUnfiltered(paint);
|
||||
tmpUnfiltered.setImageFilter(nullptr);
|
||||
this->drawSprite(draw, dst, x + offset.x(), y + offset.y(), tmpUnfiltered);
|
||||
SkBitmap resultBM;
|
||||
if (resultImg->internal_getBM(&resultBM)) {
|
||||
// TODO: add drawSprite(SkSpecialImage) to SkDevice? (see skbug.com/5073)
|
||||
this->drawSprite(draw, resultBM, x + offset.x(), y + offset.y(), tmpUnfiltered);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
this->drawSprite(draw, bitmap, x, y, paint);
|
||||
|
@ -272,7 +272,20 @@ bool SkImageFilter::filterInputDeprecated(int index, Proxy* proxy, const SkBitma
|
||||
if (!input) {
|
||||
return true;
|
||||
}
|
||||
return input->filterImageDeprecated(proxy, src, this->mapContext(ctx), result, offset);
|
||||
|
||||
SkAutoTUnref<SkSpecialImage> specialSrc(SkSpecialImage::internal_fromBM(proxy, src));
|
||||
if (!specialSrc) {
|
||||
return false;
|
||||
}
|
||||
|
||||
SkAutoTUnref<SkSpecialImage> tmp(input->onFilterImage(specialSrc,
|
||||
this->mapContext(ctx),
|
||||
offset));
|
||||
if (!tmp) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return tmp->internal_getBM(result);
|
||||
}
|
||||
|
||||
bool SkImageFilter::filterBounds(const SkIRect& src, const SkMatrix& ctm, SkIRect* dst,
|
||||
@ -327,9 +340,15 @@ bool SkImageFilter::canComputeFastBounds() const {
|
||||
|
||||
bool SkImageFilter::onFilterImageDeprecated(Proxy*, const SkBitmap&, const Context&,
|
||||
SkBitmap*, SkIPoint*) const {
|
||||
// Only classes that now use the new SkSpecialImage-based path will not have
|
||||
// onFilterImageDeprecated methods. For those classes we should never be
|
||||
// calling this method.
|
||||
SkASSERT(0);
|
||||
return false;
|
||||
}
|
||||
|
||||
// SkImageFilter-derived classes that do not yet have their own onFilterImage
|
||||
// implementation convert back to calling the deprecated filterImage method
|
||||
SkSpecialImage* SkImageFilter::onFilterImage(SkSpecialImage* src, const Context& ctx,
|
||||
SkIPoint* offset) const {
|
||||
SkBitmap srcBM, resultBM;
|
||||
@ -338,6 +357,7 @@ SkSpecialImage* SkImageFilter::onFilterImage(SkSpecialImage* src, const Context&
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// This is the only valid call to the old filterImage path
|
||||
if (!this->filterImageDeprecated(src->internal_getProxy(), srcBM, ctx, &resultBM, offset)) {
|
||||
return nullptr;
|
||||
}
|
||||
@ -583,27 +603,39 @@ bool SkImageFilter::filterInputGPUDeprecated(int index, SkImageFilter::Proxy* pr
|
||||
if (!input) {
|
||||
return true;
|
||||
}
|
||||
// Ensure that GrContext calls under filterImage and filterImageGPU below will see an identity
|
||||
// matrix with no clip and that the matrix, clip, and render target set before this function was
|
||||
// called are restored before we return to the caller.
|
||||
GrContext* context = src.getTexture()->getContext();
|
||||
if (input->filterImageDeprecated(proxy, src, this->mapContext(ctx), result, offset)) {
|
||||
if (!result->getTexture()) {
|
||||
const SkImageInfo info = result->info();
|
||||
if (kUnknown_SkColorType == info.colorType()) {
|
||||
return false;
|
||||
}
|
||||
SkAutoTUnref<GrTexture> resultTex(
|
||||
GrRefCachedBitmapTexture(context, *result, GrTextureParams::ClampNoFilter()));
|
||||
if (!resultTex) {
|
||||
return false;
|
||||
}
|
||||
result->setPixelRef(new SkGrPixelRef(info, resultTex))->unref();
|
||||
}
|
||||
return true;
|
||||
} else {
|
||||
|
||||
SkAutoTUnref<SkSpecialImage> specialSrc(SkSpecialImage::internal_fromBM(proxy, src));
|
||||
if (!specialSrc) {
|
||||
return false;
|
||||
}
|
||||
|
||||
SkAutoTUnref<SkSpecialImage> tmp(input->onFilterImage(specialSrc,
|
||||
this->mapContext(ctx),
|
||||
offset));
|
||||
if (!tmp) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!tmp->internal_getBM(result)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!result->getTexture()) {
|
||||
GrContext* context = src.getTexture()->getContext();
|
||||
|
||||
const SkImageInfo info = result->info();
|
||||
if (kUnknown_SkColorType == info.colorType()) {
|
||||
return false;
|
||||
}
|
||||
SkAutoTUnref<GrTexture> resultTex(
|
||||
GrRefCachedBitmapTexture(context, *result, GrTextureParams::ClampNoFilter()));
|
||||
if (!resultTex) {
|
||||
return false;
|
||||
}
|
||||
result->setPixelRef(new SkGrPixelRef(info, resultTex))->unref();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -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;
|
||||
|
@ -72,6 +72,13 @@ public:
|
||||
static SkSpecialImage* internal_fromBM(SkImageFilter::Proxy*, const SkBitmap&);
|
||||
SkImageFilter::Proxy* internal_getProxy();
|
||||
|
||||
// TODO: hide this when GrLayerHoister uses SkSpecialImages more fully (see skbug.com/5063)
|
||||
/**
|
||||
* If the SpecialImage is backed by a gpu texture, return that texture.
|
||||
* The active portion of the texture can be retrieved via 'subset'.
|
||||
*/
|
||||
GrTexture* peekTexture() const;
|
||||
|
||||
protected:
|
||||
SkSpecialImage(SkImageFilter::Proxy* proxy, const SkIRect& subset, uint32_t uniqueID)
|
||||
: fSubset(subset)
|
||||
@ -94,13 +101,11 @@ protected:
|
||||
*
|
||||
* On failure, return false and ignore the pixmap parameter.
|
||||
*/
|
||||
bool peekPixels(SkPixmap*) const;
|
||||
bool testingOnlyPeekPixels(SkPixmap*) const;
|
||||
|
||||
/**
|
||||
* If the SpecialImage is backed by a gpu texture, return that texture.
|
||||
* The active portion of the texture can be retrieved via 'subset'.
|
||||
*/
|
||||
GrTexture* peekTexture() const;
|
||||
// This entry point is for testing only. It does a readback from VRAM for
|
||||
// GPU-backed special images.
|
||||
bool testingOnlyGetROPixels(SkBitmap*) const;
|
||||
|
||||
// TODO: remove this ASAP (see skbug.com/4965)
|
||||
SkImageFilter::Proxy* proxy() const { return fProxy; }
|
||||
|
@ -14,6 +14,7 @@
|
||||
#include "SkGpuDevice.h"
|
||||
#include "SkLayerInfo.h"
|
||||
#include "SkRecordDraw.h"
|
||||
#include "SkSpecialImage.h"
|
||||
#include "SkSurface.h"
|
||||
#include "SkSurface_Gpu.h"
|
||||
|
||||
@ -285,18 +286,14 @@ void GrLayerHoister::FilterLayer(GrContext* context,
|
||||
|
||||
static const int kDefaultCacheSize = 32 * 1024 * 1024;
|
||||
|
||||
SkBitmap filteredBitmap;
|
||||
SkIPoint offset = SkIPoint::Make(0, 0);
|
||||
|
||||
const SkIPoint filterOffset = SkIPoint::Make(layer->srcIR().fLeft, layer->srcIR().fTop);
|
||||
|
||||
SkMatrix totMat = SkMatrix::I();
|
||||
totMat.preConcat(info.fPreMat);
|
||||
SkMatrix totMat(info.fPreMat);
|
||||
totMat.preConcat(info.fLocalMat);
|
||||
totMat.postTranslate(-SkIntToScalar(filterOffset.fX), -SkIntToScalar(filterOffset.fY));
|
||||
|
||||
SkASSERT(0 == layer->rect().fLeft && 0 == layer->rect().fTop);
|
||||
SkIRect clipBounds = layer->rect();
|
||||
const SkIRect& clipBounds = layer->rect();
|
||||
|
||||
// This cache is transient, and is freed (along with all its contained
|
||||
// textures) when it goes out of scope.
|
||||
@ -304,18 +301,24 @@ void GrLayerHoister::FilterLayer(GrContext* context,
|
||||
SkImageFilter::Context filterContext(totMat, clipBounds, cache);
|
||||
|
||||
SkImageFilter::DeviceProxy proxy(device);
|
||||
SkBitmap src;
|
||||
GrWrapTextureInBitmap(layer->texture(), layer->texture()->width(), layer->texture()->height(),
|
||||
false, &src);
|
||||
|
||||
if (!layer->filter()->filterImageDeprecated(&proxy, src, filterContext,
|
||||
&filteredBitmap, &offset)) {
|
||||
// TODO: should the layer hoister store stand alone layers as SkSpecialImages internally?
|
||||
const SkIRect subset = SkIRect::MakeWH(layer->texture()->width(), layer->texture()->height());
|
||||
SkAutoTUnref<SkSpecialImage> img(SkSpecialImage::NewFromGpu(&proxy, subset,
|
||||
kNeedNewImageUniqueID_SpecialImage,
|
||||
layer->texture()));
|
||||
|
||||
SkIPoint offset = SkIPoint::Make(0, 0);
|
||||
SkAutoTUnref<SkSpecialImage> result(layer->filter()->filterImage(img,
|
||||
filterContext,
|
||||
&offset));
|
||||
if (!result) {
|
||||
// Filtering failed. Press on with the unfiltered version.
|
||||
return;
|
||||
}
|
||||
|
||||
SkIRect newRect = SkIRect::MakeWH(filteredBitmap.width(), filteredBitmap.height());
|
||||
layer->setTexture(filteredBitmap.getTexture(), newRect, false);
|
||||
SkASSERT(result->peekTexture());
|
||||
layer->setTexture(result->peekTexture(), result->subset(), false);
|
||||
layer->setOffset(offset);
|
||||
}
|
||||
|
||||
|
@ -32,11 +32,14 @@
|
||||
#include "SkPoint3.h"
|
||||
#include "SkReadBuffer.h"
|
||||
#include "SkRect.h"
|
||||
#include "SkSpecialImage.h"
|
||||
#include "SkSpecialSurface.h"
|
||||
#include "SkSurface.h"
|
||||
#include "SkTableColorFilter.h"
|
||||
#include "SkTileImageFilter.h"
|
||||
#include "SkXfermodeImageFilter.h"
|
||||
#include "Test.h"
|
||||
#include "TestingSpecialImageAccess.h"
|
||||
|
||||
#if SK_SUPPORT_GPU
|
||||
#include "GrContext.h"
|
||||
@ -155,6 +158,35 @@ static SkImageFilter* make_blue(SkImageFilter* input, const SkImageFilter::CropR
|
||||
return SkColorFilterImageFilter::Create(filter, input, cropRect);
|
||||
}
|
||||
|
||||
static SkSpecialImage* create_empty_special_image(GrContext* context,
|
||||
SkImageFilter::Proxy* proxy,
|
||||
int widthHeight) {
|
||||
SkAutoTUnref<SkSpecialSurface> surf;
|
||||
|
||||
if (context) {
|
||||
GrSurfaceDesc desc;
|
||||
desc.fConfig = kSkia8888_GrPixelConfig;
|
||||
desc.fFlags = kRenderTarget_GrSurfaceFlag;
|
||||
desc.fWidth = widthHeight;
|
||||
desc.fHeight = widthHeight;
|
||||
surf.reset(SkSpecialSurface::NewRenderTarget(proxy, context, desc));
|
||||
} else {
|
||||
const SkImageInfo info = SkImageInfo::MakeN32(widthHeight, widthHeight,
|
||||
kOpaque_SkAlphaType);
|
||||
surf.reset(SkSpecialSurface::NewRaster(proxy, info));
|
||||
}
|
||||
|
||||
SkASSERT(surf);
|
||||
|
||||
SkCanvas* canvas = surf->getCanvas();
|
||||
SkASSERT(canvas);
|
||||
|
||||
canvas->clear(0x0);
|
||||
|
||||
return surf->newImageSnapshot();
|
||||
}
|
||||
|
||||
|
||||
DEF_TEST(ImageFilter, reporter) {
|
||||
{
|
||||
// Check that two non-clipping color-matrice-filters concatenate into a single filter.
|
||||
@ -271,13 +303,14 @@ DEF_TEST(ImageFilter, reporter) {
|
||||
}
|
||||
}
|
||||
|
||||
static void test_crop_rects(SkImageFilter::Proxy* proxy, skiatest::Reporter* reporter) {
|
||||
static void test_crop_rects(SkImageFilter::Proxy* proxy,
|
||||
skiatest::Reporter* reporter,
|
||||
GrContext* context) {
|
||||
// Check that all filters offset to their absolute crop rect,
|
||||
// unaffected by the input crop rect.
|
||||
// Tests pass by not asserting.
|
||||
SkBitmap bitmap;
|
||||
bitmap.allocN32Pixels(100, 100);
|
||||
bitmap.eraseARGB(0, 0, 0, 0);
|
||||
SkAutoTUnref<SkSpecialImage> srcImg(create_empty_special_image(context, proxy, 100));
|
||||
SkASSERT(srcImg);
|
||||
|
||||
SkImageFilter::CropRect inputCropRect(SkRect::MakeXYWH(8, 13, 80, 80));
|
||||
SkImageFilter::CropRect cropRect(SkRect::MakeXYWH(20, 30, 60, 60));
|
||||
@ -316,15 +349,12 @@ static void test_crop_rects(SkImageFilter::Proxy* proxy, skiatest::Reporter* rep
|
||||
|
||||
for (size_t i = 0; i < SK_ARRAY_COUNT(filters); ++i) {
|
||||
SkImageFilter* filter = filters[i];
|
||||
SkBitmap result;
|
||||
SkIPoint offset;
|
||||
SkString str;
|
||||
str.printf("filter %d", static_cast<int>(i));
|
||||
SkImageFilter::Context ctx(SkMatrix::I(), SkIRect::MakeWH(100, 100), nullptr);
|
||||
REPORTER_ASSERT_MESSAGE(reporter,
|
||||
filter->filterImageDeprecated(proxy, bitmap, ctx,
|
||||
&result, &offset),
|
||||
str.c_str());
|
||||
SkAutoTUnref<SkSpecialImage> resultImg(filter->filterImage(srcImg, ctx, &offset));
|
||||
REPORTER_ASSERT_MESSAGE(reporter, resultImg, str.c_str());
|
||||
REPORTER_ASSERT_MESSAGE(reporter, offset.fX == 20 && offset.fY == 30, str.c_str());
|
||||
}
|
||||
|
||||
@ -354,7 +384,11 @@ static SkBitmap make_gradient_circle(int width, int height) {
|
||||
return bitmap;
|
||||
}
|
||||
|
||||
static void test_negative_blur_sigma(SkImageFilter::Proxy* proxy, skiatest::Reporter* reporter) {
|
||||
|
||||
|
||||
static void test_negative_blur_sigma(SkImageFilter::Proxy* proxy,
|
||||
skiatest::Reporter* reporter,
|
||||
GrContext* context) {
|
||||
// Check that SkBlurImageFilter will accept a negative sigma, either in
|
||||
// the given arguments or after CTM application.
|
||||
const int width = 32, height = 32;
|
||||
@ -364,41 +398,65 @@ static void test_negative_blur_sigma(SkImageFilter::Proxy* proxy, skiatest::Repo
|
||||
SkAutoTUnref<SkImageFilter> negativeFilter(SkBlurImageFilter::Create(-five, five));
|
||||
|
||||
SkBitmap gradient = make_gradient_circle(width, height);
|
||||
SkBitmap positiveResult1, negativeResult1;
|
||||
SkBitmap positiveResult2, negativeResult2;
|
||||
SkAutoTUnref<SkSpecialImage> imgSrc(SkSpecialImage::NewFromRaster(proxy,
|
||||
SkIRect::MakeWH(width,
|
||||
height),
|
||||
gradient));
|
||||
|
||||
SkIPoint offset;
|
||||
SkImageFilter::Context ctx(SkMatrix::I(), SkIRect::MakeWH(32, 32), nullptr);
|
||||
REPORTER_ASSERT(reporter,
|
||||
positiveFilter->filterImageDeprecated(proxy, gradient, ctx,
|
||||
&positiveResult1, &offset));
|
||||
REPORTER_ASSERT(reporter,
|
||||
negativeFilter->filterImageDeprecated(proxy, gradient, ctx,
|
||||
&negativeResult1, &offset));
|
||||
|
||||
SkAutoTUnref<SkSpecialImage> positiveResult1(positiveFilter->filterImage(imgSrc, ctx, &offset));
|
||||
REPORTER_ASSERT(reporter, positiveResult1);
|
||||
|
||||
SkAutoTUnref<SkSpecialImage> negativeResult1(negativeFilter->filterImage(imgSrc, ctx, &offset));
|
||||
REPORTER_ASSERT(reporter, negativeResult1);
|
||||
|
||||
SkMatrix negativeScale;
|
||||
negativeScale.setScale(-SK_Scalar1, SK_Scalar1);
|
||||
SkImageFilter::Context negativeCTX(negativeScale, SkIRect::MakeWH(32, 32), nullptr);
|
||||
REPORTER_ASSERT(reporter,
|
||||
positiveFilter->filterImageDeprecated(proxy, gradient, negativeCTX,
|
||||
&negativeResult2, &offset));
|
||||
REPORTER_ASSERT(reporter,
|
||||
negativeFilter->filterImageDeprecated(proxy, gradient, negativeCTX,
|
||||
&positiveResult2, &offset));
|
||||
SkAutoLockPixels lockP1(positiveResult1);
|
||||
SkAutoLockPixels lockP2(positiveResult2);
|
||||
SkAutoLockPixels lockN1(negativeResult1);
|
||||
SkAutoLockPixels lockN2(negativeResult2);
|
||||
|
||||
SkAutoTUnref<SkSpecialImage> negativeResult2(positiveFilter->filterImage(imgSrc,
|
||||
negativeCTX,
|
||||
&offset));
|
||||
REPORTER_ASSERT(reporter, negativeResult2);
|
||||
|
||||
SkAutoTUnref<SkSpecialImage> positiveResult2(negativeFilter->filterImage(imgSrc,
|
||||
negativeCTX,
|
||||
&offset));
|
||||
REPORTER_ASSERT(reporter, positiveResult2);
|
||||
|
||||
|
||||
SkBitmap positiveResultBM1, positiveResultBM2;
|
||||
SkBitmap negativeResultBM1, negativeResultBM2;
|
||||
|
||||
TestingSpecialImageAccess::GetROPixels(positiveResult1, &positiveResultBM1);
|
||||
TestingSpecialImageAccess::GetROPixels(positiveResult2, &positiveResultBM2);
|
||||
TestingSpecialImageAccess::GetROPixels(negativeResult1, &negativeResultBM1);
|
||||
TestingSpecialImageAccess::GetROPixels(negativeResult2, &negativeResultBM2);
|
||||
|
||||
SkAutoLockPixels lockP1(positiveResultBM1);
|
||||
SkAutoLockPixels lockP2(positiveResultBM2);
|
||||
SkAutoLockPixels lockN1(negativeResultBM1);
|
||||
SkAutoLockPixels lockN2(negativeResultBM2);
|
||||
for (int y = 0; y < height; y++) {
|
||||
int diffs = memcmp(positiveResult1.getAddr32(0, y), negativeResult1.getAddr32(0, y), positiveResult1.rowBytes());
|
||||
int diffs = memcmp(positiveResultBM1.getAddr32(0, y),
|
||||
negativeResultBM1.getAddr32(0, y),
|
||||
positiveResultBM1.rowBytes());
|
||||
REPORTER_ASSERT(reporter, !diffs);
|
||||
if (diffs) {
|
||||
break;
|
||||
}
|
||||
diffs = memcmp(positiveResult1.getAddr32(0, y), negativeResult2.getAddr32(0, y), positiveResult1.rowBytes());
|
||||
diffs = memcmp(positiveResultBM1.getAddr32(0, y),
|
||||
negativeResultBM2.getAddr32(0, y),
|
||||
positiveResultBM1.rowBytes());
|
||||
REPORTER_ASSERT(reporter, !diffs);
|
||||
if (diffs) {
|
||||
break;
|
||||
}
|
||||
diffs = memcmp(positiveResult1.getAddr32(0, y), positiveResult2.getAddr32(0, y), positiveResult1.rowBytes());
|
||||
diffs = memcmp(positiveResultBM1.getAddr32(0, y),
|
||||
positiveResultBM2.getAddr32(0, y),
|
||||
positiveResultBM1.rowBytes());
|
||||
REPORTER_ASSERT(reporter, !diffs);
|
||||
if (diffs) {
|
||||
break;
|
||||
@ -406,16 +464,53 @@ static void test_negative_blur_sigma(SkImageFilter::Proxy* proxy, skiatest::Repo
|
||||
}
|
||||
}
|
||||
|
||||
DEF_TEST(TestNegativeBlurSigma, reporter) {
|
||||
const SkImageInfo info = SkImageInfo::MakeN32Premul(100, 100);
|
||||
typedef void (*PFTest)(SkImageFilter::Proxy* proxy,
|
||||
skiatest::Reporter* reporter,
|
||||
GrContext* context);
|
||||
|
||||
static void run_raster_test(skiatest::Reporter* reporter,
|
||||
int widthHeight,
|
||||
PFTest test) {
|
||||
const SkSurfaceProps props(SkSurfaceProps::kLegacyFontHost_InitType);
|
||||
|
||||
const SkImageInfo info = SkImageInfo::MakeN32Premul(widthHeight, widthHeight);
|
||||
|
||||
SkAutoTUnref<SkBaseDevice> device(SkBitmapDevice::Create(info, props));
|
||||
SkImageFilter::DeviceProxy proxy(device);
|
||||
|
||||
test_negative_blur_sigma(&proxy, reporter);
|
||||
(*test)(&proxy, reporter, nullptr);
|
||||
}
|
||||
|
||||
#if SK_SUPPORT_GPU
|
||||
static void run_gpu_test(skiatest::Reporter* reporter,
|
||||
GrContext* context,
|
||||
int widthHeight,
|
||||
PFTest test) {
|
||||
const SkSurfaceProps props(SkSurfaceProps::kLegacyFontHost_InitType);
|
||||
|
||||
SkAutoTUnref<SkGpuDevice> device(SkGpuDevice::Create(context,
|
||||
SkBudgeted::kNo,
|
||||
SkImageInfo::MakeN32Premul(widthHeight,
|
||||
widthHeight),
|
||||
0,
|
||||
&props,
|
||||
SkGpuDevice::kUninit_InitContents));
|
||||
SkImageFilter::DeviceProxy proxy(device);
|
||||
|
||||
(*test)(&proxy, reporter, context);
|
||||
}
|
||||
#endif
|
||||
|
||||
DEF_TEST(TestNegativeBlurSigma, reporter) {
|
||||
run_raster_test(reporter, 100, test_negative_blur_sigma);
|
||||
}
|
||||
|
||||
#if SK_SUPPORT_GPU
|
||||
DEF_GPUTEST_FOR_NATIVE_CONTEXT(TestNegativeBlurSigma_Gpu, reporter, context) {
|
||||
run_gpu_test(reporter, context, 100, test_negative_blur_sigma);
|
||||
}
|
||||
#endif
|
||||
|
||||
DEF_TEST(ImageFilterDrawTiled, reporter) {
|
||||
// Check that all filters when drawn tiled (with subsequent clip rects) exactly
|
||||
// match the same filters drawn with a single full-canvas bitmap draw.
|
||||
@ -654,7 +749,9 @@ DEF_TEST(ImageFilterComposedBlurFastBounds, reporter) {
|
||||
REPORTER_ASSERT(reporter, boundsDst == expectedBounds);
|
||||
}
|
||||
|
||||
DEF_TEST(ImageFilterMergeResultSize, reporter) {
|
||||
static void test_imagefilter_merge_result_size(SkImageFilter::Proxy* proxy,
|
||||
skiatest::Reporter* reporter,
|
||||
GrContext* context) {
|
||||
SkBitmap greenBM;
|
||||
greenBM.allocN32Pixels(20, 20);
|
||||
greenBM.eraseColor(SK_ColorGREEN);
|
||||
@ -662,20 +759,27 @@ DEF_TEST(ImageFilterMergeResultSize, reporter) {
|
||||
SkAutoTUnref<SkImageFilter> source(SkImageSource::Create(greenImage.get()));
|
||||
SkAutoTUnref<SkImageFilter> merge(SkMergeImageFilter::Create(source.get(), source.get()));
|
||||
|
||||
SkBitmap bitmap;
|
||||
bitmap.allocN32Pixels(1, 1);
|
||||
bitmap.eraseColor(0);
|
||||
const SkImageInfo info = SkImageInfo::MakeN32Premul(100, 100);
|
||||
const SkSurfaceProps props(SkSurfaceProps::kLegacyFontHost_InitType);
|
||||
SkAutoTUnref<SkBaseDevice> device(SkBitmapDevice::Create(info, props));
|
||||
SkImageFilter::DeviceProxy proxy(device);
|
||||
SkAutoTUnref<SkSpecialImage> srcImg(create_empty_special_image(context, proxy, 1));
|
||||
|
||||
SkImageFilter::Context ctx(SkMatrix::I(), SkIRect::MakeXYWH(0, 0, 100, 100), nullptr);
|
||||
SkBitmap result;
|
||||
SkIPoint offset;
|
||||
REPORTER_ASSERT(reporter, merge->filterImageDeprecated(&proxy, bitmap, ctx, &result, &offset));
|
||||
REPORTER_ASSERT(reporter, result.width() == 20 && result.height() == 20);
|
||||
|
||||
SkAutoTUnref<SkSpecialImage> resultImg(merge->filterImage(srcImg, ctx, &offset));
|
||||
REPORTER_ASSERT(reporter, resultImg);
|
||||
|
||||
REPORTER_ASSERT(reporter, resultImg->width() == 20 && resultImg->height() == 20);
|
||||
}
|
||||
|
||||
DEF_TEST(ImageFilterMergeResultSize, reporter) {
|
||||
run_raster_test(reporter, 100, test_imagefilter_merge_result_size);
|
||||
}
|
||||
|
||||
#if SK_SUPPORT_GPU
|
||||
DEF_GPUTEST_FOR_NATIVE_CONTEXT(ImageFilterMergeResultSize_Gpu, reporter, context) {
|
||||
run_gpu_test(reporter, context, 100, test_imagefilter_merge_result_size);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void draw_blurred_rect(SkCanvas* canvas) {
|
||||
SkAutoTUnref<SkImageFilter> filter(SkBlurImageFilter::Create(SkIntToScalar(8), 0));
|
||||
SkPaint filterPaint;
|
||||
@ -803,15 +907,15 @@ DEF_TEST(ImageFilterMatrixConvolutionBorder, reporter) {
|
||||
}
|
||||
|
||||
DEF_TEST(ImageFilterCropRect, reporter) {
|
||||
const SkImageInfo info = SkImageInfo::MakeN32Premul(100, 100);
|
||||
const SkSurfaceProps props(SkSurfaceProps::kLegacyFontHost_InitType);
|
||||
|
||||
SkAutoTUnref<SkBaseDevice> device(SkBitmapDevice::Create(info, props));
|
||||
SkImageFilter::DeviceProxy proxy(device);
|
||||
|
||||
test_crop_rects(&proxy, reporter);
|
||||
run_raster_test(reporter, 100, test_crop_rects);
|
||||
}
|
||||
|
||||
#if SK_SUPPORT_GPU
|
||||
DEF_GPUTEST_FOR_NATIVE_CONTEXT(ImageFilterCropRect_Gpu, reporter, context) {
|
||||
run_gpu_test(reporter, context, 100, test_crop_rects);
|
||||
}
|
||||
#endif
|
||||
|
||||
DEF_TEST(ImageFilterMatrix, reporter) {
|
||||
SkBitmap temp;
|
||||
temp.allocN32Pixels(100, 100);
|
||||
@ -901,31 +1005,44 @@ DEF_TEST(ImageFilterCrossProcessPictureImageFilter, reporter) {
|
||||
? pixel != SK_ColorGREEN : pixel == SK_ColorGREEN);
|
||||
}
|
||||
|
||||
DEF_TEST(ImageFilterClippedPictureImageFilter, reporter) {
|
||||
SkRTreeFactory factory;
|
||||
SkPictureRecorder recorder;
|
||||
SkCanvas* recordingCanvas = recorder.beginRecording(1, 1, &factory, 0);
|
||||
static void test_clipped_picture_imagefilter(SkImageFilter::Proxy* proxy,
|
||||
skiatest::Reporter* reporter,
|
||||
GrContext* context) {
|
||||
SkAutoTUnref<SkPicture> picture;
|
||||
|
||||
// Create an SkPicture which simply draws a green 1x1 rectangle.
|
||||
SkPaint greenPaint;
|
||||
greenPaint.setColor(SK_ColorGREEN);
|
||||
recordingCanvas->drawRect(SkRect::Make(SkIRect::MakeWH(1, 1)), greenPaint);
|
||||
SkAutoTUnref<SkPicture> picture(recorder.endRecording());
|
||||
{
|
||||
SkRTreeFactory factory;
|
||||
SkPictureRecorder recorder;
|
||||
SkCanvas* recordingCanvas = recorder.beginRecording(1, 1, &factory, 0);
|
||||
|
||||
// Create an SkPicture which simply draws a green 1x1 rectangle.
|
||||
SkPaint greenPaint;
|
||||
greenPaint.setColor(SK_ColorGREEN);
|
||||
recordingCanvas->drawRect(SkRect::Make(SkIRect::MakeWH(1, 1)), greenPaint);
|
||||
picture.reset(recorder.endRecording());
|
||||
}
|
||||
|
||||
SkAutoTUnref<SkSpecialImage> srcImg(create_empty_special_image(context, proxy, 2));
|
||||
|
||||
SkAutoTUnref<SkImageFilter> imageFilter(SkPictureImageFilter::Create(picture.get()));
|
||||
|
||||
SkBitmap result;
|
||||
SkIPoint offset;
|
||||
SkImageFilter::Context ctx(SkMatrix::I(), SkIRect::MakeXYWH(1, 1, 1, 1), nullptr);
|
||||
SkBitmap bitmap;
|
||||
bitmap.allocN32Pixels(2, 2);
|
||||
const SkSurfaceProps props(SkSurfaceProps::kLegacyFontHost_InitType);
|
||||
SkBitmapDevice device(bitmap, props);
|
||||
SkImageFilter::DeviceProxy proxy(&device);
|
||||
REPORTER_ASSERT(reporter,
|
||||
!imageFilter->filterImageDeprecated(&proxy, bitmap, ctx, &result, &offset));
|
||||
|
||||
SkAutoTUnref<SkSpecialImage> resultImage(imageFilter->filterImage(srcImg, ctx, &offset));
|
||||
REPORTER_ASSERT(reporter, !resultImage);
|
||||
}
|
||||
|
||||
DEF_TEST(ImageFilterClippedPictureImageFilter, reporter) {
|
||||
run_raster_test(reporter, 2, test_clipped_picture_imagefilter);
|
||||
}
|
||||
|
||||
#if SK_SUPPORT_GPU
|
||||
DEF_GPUTEST_FOR_NATIVE_CONTEXT(ImageFilterClippedPictureImageFilter_Gpu, reporter, context) {
|
||||
run_gpu_test(reporter, context, 2, test_clipped_picture_imagefilter);
|
||||
}
|
||||
#endif
|
||||
|
||||
DEF_TEST(ImageFilterEmptySaveLayer, reporter) {
|
||||
// Even when there's an empty saveLayer()/restore(), ensure that an image
|
||||
// filter or color filter which affects transparent black still draws.
|
||||
@ -1154,13 +1271,10 @@ DEF_TEST(XfermodeImageFilterCroppedInput, reporter) {
|
||||
test_xfermode_cropped_input(&canvas, reporter);
|
||||
}
|
||||
|
||||
DEF_TEST(ComposedImageFilterOffset, reporter) {
|
||||
SkBitmap bitmap;
|
||||
bitmap.allocN32Pixels(100, 100);
|
||||
bitmap.eraseARGB(0, 0, 0, 0);
|
||||
const SkSurfaceProps props(SkSurfaceProps::kLegacyFontHost_InitType);
|
||||
SkBitmapDevice device(bitmap, props);
|
||||
SkImageFilter::DeviceProxy proxy(&device);
|
||||
static void test_composed_imagefilter_offset(SkImageFilter::Proxy* proxy,
|
||||
skiatest::Reporter* reporter,
|
||||
GrContext* context) {
|
||||
SkAutoTUnref<SkSpecialImage> srcImg(create_empty_special_image(context, proxy, 100));
|
||||
|
||||
SkImageFilter::CropRect cropRect(SkRect::MakeXYWH(1, 0, 20, 20));
|
||||
SkAutoTUnref<SkImageFilter> offsetFilter(SkOffsetImageFilter::Create(0, 0, nullptr, &cropRect));
|
||||
@ -1168,36 +1282,54 @@ DEF_TEST(ComposedImageFilterOffset, reporter) {
|
||||
nullptr, &cropRect));
|
||||
SkAutoTUnref<SkImageFilter> composedFilter(SkComposeImageFilter::Create(blurFilter,
|
||||
offsetFilter.get()));
|
||||
SkBitmap result;
|
||||
SkIPoint offset;
|
||||
SkImageFilter::Context ctx(SkMatrix::I(), SkIRect::MakeWH(100, 100), nullptr);
|
||||
REPORTER_ASSERT(reporter,
|
||||
composedFilter->filterImageDeprecated(&proxy, bitmap, ctx, &result, &offset));
|
||||
|
||||
SkAutoTUnref<SkSpecialImage> resultImg(composedFilter->filterImage(srcImg, ctx, &offset));
|
||||
REPORTER_ASSERT(reporter, resultImg);
|
||||
REPORTER_ASSERT(reporter, offset.fX == 1 && offset.fY == 0);
|
||||
}
|
||||
|
||||
DEF_TEST(PartialCropRect, reporter) {
|
||||
SkBitmap bitmap;
|
||||
bitmap.allocN32Pixels(100, 100);
|
||||
bitmap.eraseARGB(0, 0, 0, 0);
|
||||
const SkSurfaceProps props(SkSurfaceProps::kLegacyFontHost_InitType);
|
||||
SkBitmapDevice device(bitmap, props);
|
||||
SkImageFilter::DeviceProxy proxy(&device);
|
||||
DEF_TEST(ComposedImageFilterOffset, reporter) {
|
||||
run_raster_test(reporter, 100, test_composed_imagefilter_offset);
|
||||
}
|
||||
|
||||
#if SK_SUPPORT_GPU
|
||||
DEF_GPUTEST_FOR_NATIVE_CONTEXT(ComposedImageFilterOffset_Gpu, reporter, context) {
|
||||
run_gpu_test(reporter, context, 100, test_composed_imagefilter_offset);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void test_partial_crop_rect(SkImageFilter::Proxy* proxy,
|
||||
skiatest::Reporter* reporter,
|
||||
GrContext* context) {
|
||||
SkAutoTUnref<SkSpecialImage> srcImg(create_empty_special_image(context, proxy, 100));
|
||||
|
||||
SkImageFilter::CropRect cropRect(SkRect::MakeXYWH(100, 0, 20, 30),
|
||||
SkImageFilter::CropRect::kHasWidth_CropEdge | SkImageFilter::CropRect::kHasHeight_CropEdge);
|
||||
SkAutoTUnref<SkImageFilter> filter(make_grayscale(nullptr, &cropRect));
|
||||
SkBitmap result;
|
||||
SkIPoint offset;
|
||||
SkImageFilter::Context ctx(SkMatrix::I(), SkIRect::MakeWH(100, 100), nullptr);
|
||||
REPORTER_ASSERT(reporter,
|
||||
filter->filterImageDeprecated(&proxy, bitmap, ctx, &result, &offset));
|
||||
|
||||
SkAutoTUnref<SkSpecialImage> resultImg(filter->filterImage(srcImg, ctx, &offset));
|
||||
REPORTER_ASSERT(reporter, resultImg);
|
||||
|
||||
REPORTER_ASSERT(reporter, offset.fX == 0);
|
||||
REPORTER_ASSERT(reporter, offset.fY == 0);
|
||||
REPORTER_ASSERT(reporter, result.width() == 20);
|
||||
REPORTER_ASSERT(reporter, result.height() == 30);
|
||||
REPORTER_ASSERT(reporter, resultImg->width() == 20);
|
||||
REPORTER_ASSERT(reporter, resultImg->height() == 30);
|
||||
}
|
||||
|
||||
DEF_TEST(PartialCropRect, reporter) {
|
||||
run_raster_test(reporter, 100, test_partial_crop_rect);
|
||||
}
|
||||
|
||||
#if SK_SUPPORT_GPU
|
||||
DEF_GPUTEST_FOR_NATIVE_CONTEXT(PartialCropRect_Gpu, reporter, context) {
|
||||
run_gpu_test(reporter, context, 100, test_partial_crop_rect);
|
||||
}
|
||||
#endif
|
||||
|
||||
DEF_TEST(ImageFilterCanComputeFastBounds, reporter) {
|
||||
|
||||
SkPoint3 location = SkPoint3::Make(0, 0, SK_Scalar1);
|
||||
@ -1325,20 +1457,6 @@ DEF_TEST(BlurLargeImage, reporter) {
|
||||
|
||||
#if SK_SUPPORT_GPU
|
||||
|
||||
DEF_GPUTEST_FOR_NATIVE_CONTEXT(ImageFilterCropRect_Gpu, reporter, context) {
|
||||
const SkSurfaceProps props(SkSurfaceProps::kLegacyFontHost_InitType);
|
||||
|
||||
SkAutoTUnref<SkGpuDevice> device(SkGpuDevice::Create(context,
|
||||
SkBudgeted::kNo,
|
||||
SkImageInfo::MakeN32Premul(100, 100),
|
||||
0,
|
||||
&props,
|
||||
SkGpuDevice::kUninit_InitContents));
|
||||
SkImageFilter::DeviceProxy proxy(device);
|
||||
|
||||
test_crop_rects(&proxy, reporter);
|
||||
}
|
||||
|
||||
DEF_GPUTEST_FOR_NATIVE_CONTEXT(HugeBlurImageFilter_Gpu, reporter, context) {
|
||||
const SkSurfaceProps props(SkSurfaceProps::kLegacyFontHost_InitType);
|
||||
|
||||
@ -1367,20 +1485,6 @@ DEF_GPUTEST_FOR_NATIVE_CONTEXT(XfermodeImageFilterCroppedInput_Gpu, reporter, co
|
||||
test_xfermode_cropped_input(&canvas, reporter);
|
||||
}
|
||||
|
||||
DEF_GPUTEST_FOR_NATIVE_CONTEXT(TestNegativeBlurSigma_Gpu, reporter, context) {
|
||||
const SkSurfaceProps props(SkSurfaceProps::kLegacyFontHost_InitType);
|
||||
|
||||
SkAutoTUnref<SkGpuDevice> device(SkGpuDevice::Create(context,
|
||||
SkBudgeted::kNo,
|
||||
SkImageInfo::MakeN32Premul(1, 1),
|
||||
0,
|
||||
&props,
|
||||
SkGpuDevice::kUninit_InitContents));
|
||||
SkImageFilter::DeviceProxy proxy(device);
|
||||
|
||||
test_negative_blur_sigma(&proxy, reporter);
|
||||
}
|
||||
|
||||
DEF_GPUTEST_FOR_ALL_CONTEXTS(BlurLargeImage_Gpu, reporter, context) {
|
||||
SkAutoTUnref<SkSurface> surface(
|
||||
SkSurface::NewRenderTarget(context, SkBudgeted::kYes,
|
||||
|
@ -11,25 +11,12 @@
|
||||
#include "SkSpecialImage.h"
|
||||
#include "SkSpecialSurface.h"
|
||||
#include "Test.h"
|
||||
#include "TestingSpecialImageAccess.h"
|
||||
|
||||
#if SK_SUPPORT_GPU
|
||||
#include "GrContext.h"
|
||||
#endif
|
||||
|
||||
class TestingSpecialImageAccess {
|
||||
public:
|
||||
static const SkIRect& Subset(const SkSpecialImage* img) {
|
||||
return img->subset();
|
||||
}
|
||||
|
||||
static bool PeekPixels(const SkSpecialImage* img, SkPixmap* pixmap) {
|
||||
return img->peekPixels(pixmap);
|
||||
}
|
||||
|
||||
static GrTexture* PeekTexture(const SkSpecialImage* img) {
|
||||
return img->peekTexture();
|
||||
}
|
||||
};
|
||||
|
||||
// This test creates backing resources exactly sized to [kFullSize x kFullSize].
|
||||
// It then wraps them in an SkSpecialImage with only the center (red) region being active.
|
||||
|
30
tests/TestingSpecialImageAccess.h
Normal file
30
tests/TestingSpecialImageAccess.h
Normal file
@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright 2016 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file
|
||||
*/
|
||||
|
||||
#ifndef TestingSpecialImageAccess_DEFINED
|
||||
#define TestingSpecialImageAccess_DEFINED
|
||||
|
||||
class TestingSpecialImageAccess {
|
||||
public:
|
||||
static const SkIRect& Subset(const SkSpecialImage* img) {
|
||||
return img->subset();
|
||||
}
|
||||
|
||||
static bool PeekPixels(const SkSpecialImage* img, SkPixmap* pixmap) {
|
||||
return img->testingOnlyPeekPixels(pixmap);
|
||||
}
|
||||
|
||||
static GrTexture* PeekTexture(const SkSpecialImage* img) {
|
||||
return img->peekTexture();
|
||||
}
|
||||
|
||||
static bool GetROPixels(const SkSpecialImage* img, SkBitmap* result) {
|
||||
return img->testingOnlyGetROPixels(result);
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user