Fix image filter crop offsets for GPU path.
This is the GPU-side version of https://codereview.chromium.org/112803004/. Also factored the crop offset unit test into a function, so we can call it with both CPU & GPU devices. R=bsalomon@google.com Review URL: https://codereview.chromium.org/153113003 git-svn-id: http://skia.googlecode.com/svn/trunk@13292 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
parent
29af1f35d7
commit
aba651c3f1
@ -148,12 +148,14 @@ bool SkImageFilter::filterImageGPU(Proxy* proxy, const SkBitmap& src, const SkMa
|
||||
#if SK_SUPPORT_GPU
|
||||
SkBitmap input;
|
||||
SkASSERT(fInputCount == 1);
|
||||
if (!SkImageFilterUtils::GetInputResultGPU(this->getInput(0), proxy, src, ctm, &input, offset)) {
|
||||
SkIPoint srcOffset = SkIPoint::Make(0, 0);
|
||||
if (!SkImageFilterUtils::GetInputResultGPU(this->getInput(0), proxy, src, ctm, &input, &srcOffset)) {
|
||||
return false;
|
||||
}
|
||||
GrTexture* srcTexture = input.getTexture();
|
||||
SkIRect bounds;
|
||||
src.getBounds(&bounds);
|
||||
bounds.offset(srcOffset);
|
||||
if (!this->applyCropRect(&bounds, ctm)) {
|
||||
return false;
|
||||
}
|
||||
@ -173,6 +175,9 @@ bool SkImageFilter::filterImageGPU(Proxy* proxy, const SkBitmap& src, const SkMa
|
||||
GrContext::AutoRenderTarget art(context, dst.texture()->asRenderTarget());
|
||||
GrContext::AutoClip acs(context, dstRect);
|
||||
GrEffectRef* effect;
|
||||
offset->fX = bounds.left();
|
||||
offset->fY = bounds.top();
|
||||
bounds.offset(-srcOffset);
|
||||
SkMatrix matrix(ctm);
|
||||
matrix.postTranslate(SkIntToScalar(-bounds.left()), SkIntToScalar(-bounds.top()));
|
||||
this->asNewEffect(&effect, srcTexture, matrix, bounds);
|
||||
@ -184,8 +189,6 @@ bool SkImageFilter::filterImageGPU(Proxy* proxy, const SkBitmap& src, const SkMa
|
||||
|
||||
SkAutoTUnref<GrTexture> resultTex(dst.detach());
|
||||
SkImageFilterUtils::WrapTexture(resultTex, bounds.width(), bounds.height(), result);
|
||||
offset->fX += bounds.left();
|
||||
offset->fY += bounds.top();
|
||||
return true;
|
||||
#else
|
||||
return false;
|
||||
|
@ -240,17 +240,22 @@ bool SkBlurImageFilter::filterImageGPU(Proxy* proxy, const SkBitmap& src, const
|
||||
SkBitmap* result, SkIPoint* offset) {
|
||||
#if SK_SUPPORT_GPU
|
||||
SkBitmap input;
|
||||
if (!SkImageFilterUtils::GetInputResultGPU(getInput(0), proxy, src, ctm, &input, offset)) {
|
||||
SkIPoint srcOffset = SkIPoint::Make(0, 0);
|
||||
if (!SkImageFilterUtils::GetInputResultGPU(getInput(0), proxy, src, ctm, &input, &srcOffset)) {
|
||||
return false;
|
||||
}
|
||||
GrTexture* source = input.getTexture();
|
||||
SkIRect rect;
|
||||
src.getBounds(&rect);
|
||||
rect.offset(srcOffset);
|
||||
if (!this->applyCropRect(&rect, ctm)) {
|
||||
return false;
|
||||
}
|
||||
SkVector sigma, localSigma = SkVector::Make(fSigma.width(), fSigma.height());
|
||||
ctm.mapVectors(&sigma, &localSigma, 1);
|
||||
offset->fX = rect.fLeft;
|
||||
offset->fY = rect.fTop;
|
||||
rect.offset(-srcOffset);
|
||||
SkAutoTUnref<GrTexture> tex(SkGpuBlurUtils::GaussianBlur(source->getContext(),
|
||||
source,
|
||||
false,
|
||||
@ -258,8 +263,6 @@ bool SkBlurImageFilter::filterImageGPU(Proxy* proxy, const SkBitmap& src, const
|
||||
true,
|
||||
sigma.x(),
|
||||
sigma.y()));
|
||||
offset->fX = rect.fLeft;
|
||||
offset->fY = rect.fTop;
|
||||
return SkImageFilterUtils::WrapTexture(tex, rect.width(), rect.height(), result);
|
||||
#else
|
||||
SkDEBUGFAIL("Should not call in GPU-less build");
|
||||
|
@ -26,6 +26,11 @@
|
||||
#include "SkXfermodeImageFilter.h"
|
||||
#include "Test.h"
|
||||
|
||||
#if SK_SUPPORT_GPU
|
||||
#include "GrContextFactory.h"
|
||||
#include "SkGpuDevice.h"
|
||||
#endif
|
||||
|
||||
static const int kBitmapSize = 4;
|
||||
|
||||
static void make_small_bitmap(SkBitmap& bitmap) {
|
||||
@ -156,64 +161,77 @@ DEF_TEST(ImageFilter, reporter) {
|
||||
!bicubic->filterImage(&proxy, bitmap, SkMatrix::I(), &result, &loc));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
// Check that all filters offset to their absolute crop rect,
|
||||
// unaffected by the input crop rect.
|
||||
// Tests pass by not asserting.
|
||||
SkBitmap bitmap, temp;
|
||||
bitmap.setConfig(SkBitmap::kARGB_8888_Config, 100, 100);
|
||||
temp.setConfig(SkBitmap::kARGB_8888_Config, 100, 100);
|
||||
bitmap.allocPixels();
|
||||
temp.allocPixels();
|
||||
bitmap.eraseARGB(0, 0, 0, 0);
|
||||
SkBitmapDevice device(temp);
|
||||
SkDeviceImageFilterProxy proxy(&device);
|
||||
static void test_crop_rects(SkBaseDevice* device, skiatest::Reporter* reporter) {
|
||||
// Check that all filters offset to their absolute crop rect,
|
||||
// unaffected by the input crop rect.
|
||||
// Tests pass by not asserting.
|
||||
SkBitmap bitmap;
|
||||
bitmap.setConfig(SkBitmap::kARGB_8888_Config, 100, 100);
|
||||
bitmap.allocPixels();
|
||||
bitmap.eraseARGB(0, 0, 0, 0);
|
||||
SkDeviceImageFilterProxy proxy(device);
|
||||
|
||||
SkImageFilter::CropRect inputCropRect(SkRect::MakeXYWH(8, 13, 80, 80));
|
||||
SkImageFilter::CropRect cropRect(SkRect::MakeXYWH(20, 30, 60, 60));
|
||||
SkAutoTUnref<SkImageFilter> input(make_grayscale(NULL, &inputCropRect));
|
||||
SkImageFilter::CropRect inputCropRect(SkRect::MakeXYWH(8, 13, 80, 80));
|
||||
SkImageFilter::CropRect cropRect(SkRect::MakeXYWH(20, 30, 60, 60));
|
||||
SkAutoTUnref<SkImageFilter> input(make_grayscale(NULL, &inputCropRect));
|
||||
|
||||
SkAutoTUnref<SkColorFilter> cf(SkColorFilter::CreateModeFilter(SK_ColorRED, SkXfermode::kSrcIn_Mode));
|
||||
SkPoint3 location(0, 0, SK_Scalar1);
|
||||
SkPoint3 target(SK_Scalar1, SK_Scalar1, SK_Scalar1);
|
||||
SkScalar kernel[9] = {
|
||||
SkIntToScalar( 1), SkIntToScalar( 1), SkIntToScalar( 1),
|
||||
SkIntToScalar( 1), SkIntToScalar(-7), SkIntToScalar( 1),
|
||||
SkIntToScalar( 1), SkIntToScalar( 1), SkIntToScalar( 1),
|
||||
};
|
||||
SkISize kernelSize = SkISize::Make(3, 3);
|
||||
SkScalar gain = SK_Scalar1, bias = 0;
|
||||
SkAutoTUnref<SkColorFilter> cf(SkColorFilter::CreateModeFilter(SK_ColorRED, SkXfermode::kSrcIn_Mode));
|
||||
SkPoint3 location(0, 0, SK_Scalar1);
|
||||
SkPoint3 target(SK_Scalar1, SK_Scalar1, SK_Scalar1);
|
||||
SkScalar kernel[9] = {
|
||||
SkIntToScalar( 1), SkIntToScalar( 1), SkIntToScalar( 1),
|
||||
SkIntToScalar( 1), SkIntToScalar(-7), SkIntToScalar( 1),
|
||||
SkIntToScalar( 1), SkIntToScalar( 1), SkIntToScalar( 1),
|
||||
};
|
||||
SkISize kernelSize = SkISize::Make(3, 3);
|
||||
SkScalar gain = SK_Scalar1, bias = 0;
|
||||
|
||||
SkImageFilter* filters[] = {
|
||||
SkColorFilterImageFilter::Create(cf.get(), input.get(), &cropRect),
|
||||
new SkDisplacementMapEffect(SkDisplacementMapEffect::kR_ChannelSelectorType,
|
||||
SkDisplacementMapEffect::kB_ChannelSelectorType,
|
||||
40.0f, input.get(), input.get(), &cropRect),
|
||||
new SkBlurImageFilter(SK_Scalar1, SK_Scalar1, input.get(), &cropRect),
|
||||
new SkDropShadowImageFilter(SK_Scalar1, SK_Scalar1, SK_Scalar1, SK_Scalar1, SK_ColorGREEN, input.get(), &cropRect),
|
||||
SkLightingImageFilter::CreatePointLitDiffuse(location, SK_ColorGREEN, 0, 0, input.get(), &cropRect),
|
||||
SkLightingImageFilter::CreatePointLitSpecular(location, SK_ColorGREEN, 0, 0, 0, input.get(), &cropRect),
|
||||
new SkMatrixConvolutionImageFilter(kernelSize, kernel, gain, bias, SkIPoint::Make(1, 1), SkMatrixConvolutionImageFilter::kRepeat_TileMode, false, input.get(), &cropRect),
|
||||
new SkMergeImageFilter(input.get(), input.get(), SkXfermode::kSrcOver_Mode, &cropRect),
|
||||
new SkOffsetImageFilter(SK_Scalar1, SK_Scalar1, input.get(), &cropRect),
|
||||
new SkOffsetImageFilter(SK_Scalar1, SK_Scalar1, input.get(), &cropRect),
|
||||
new SkDilateImageFilter(3, 2, input.get(), &cropRect),
|
||||
new SkErodeImageFilter(2, 3, input.get(), &cropRect),
|
||||
new SkTileImageFilter(inputCropRect.rect(), cropRect.rect(), input.get()),
|
||||
new SkXfermodeImageFilter(SkXfermode::Create(SkXfermode::kSrcOver_Mode), input.get(), input.get(), &cropRect),
|
||||
};
|
||||
SkImageFilter* filters[] = {
|
||||
SkColorFilterImageFilter::Create(cf.get(), input.get(), &cropRect),
|
||||
new SkDisplacementMapEffect(SkDisplacementMapEffect::kR_ChannelSelectorType,
|
||||
SkDisplacementMapEffect::kB_ChannelSelectorType,
|
||||
40.0f, input.get(), input.get(), &cropRect),
|
||||
new SkBlurImageFilter(SK_Scalar1, SK_Scalar1, input.get(), &cropRect),
|
||||
new SkDropShadowImageFilter(SK_Scalar1, SK_Scalar1, SK_Scalar1, SK_Scalar1, SK_ColorGREEN, input.get(), &cropRect),
|
||||
SkLightingImageFilter::CreatePointLitDiffuse(location, SK_ColorGREEN, 0, 0, input.get(), &cropRect),
|
||||
SkLightingImageFilter::CreatePointLitSpecular(location, SK_ColorGREEN, 0, 0, 0, input.get(), &cropRect),
|
||||
new SkMatrixConvolutionImageFilter(kernelSize, kernel, gain, bias, SkIPoint::Make(1, 1), SkMatrixConvolutionImageFilter::kRepeat_TileMode, false, input.get(), &cropRect),
|
||||
new SkMergeImageFilter(input.get(), input.get(), SkXfermode::kSrcOver_Mode, &cropRect),
|
||||
new SkOffsetImageFilter(SK_Scalar1, SK_Scalar1, input.get(), &cropRect),
|
||||
new SkOffsetImageFilter(SK_Scalar1, SK_Scalar1, input.get(), &cropRect),
|
||||
new SkDilateImageFilter(3, 2, input.get(), &cropRect),
|
||||
new SkErodeImageFilter(2, 3, input.get(), &cropRect),
|
||||
new SkTileImageFilter(inputCropRect.rect(), cropRect.rect(), input.get()),
|
||||
new SkXfermodeImageFilter(SkXfermode::Create(SkXfermode::kSrcOver_Mode), input.get(), input.get(), &cropRect),
|
||||
};
|
||||
|
||||
for (size_t i = 0; i < SK_ARRAY_COUNT(filters); ++i) {
|
||||
SkImageFilter* filter = filters[i];
|
||||
SkBitmap result;
|
||||
SkIPoint offset;
|
||||
REPORTER_ASSERT(reporter, filter->filterImage(&proxy, bitmap, SkMatrix::I(), &result, &offset));
|
||||
REPORTER_ASSERT(reporter, offset.fX == 20 && offset.fY == 30);
|
||||
}
|
||||
for (size_t i = 0; i < SK_ARRAY_COUNT(filters); ++i) {
|
||||
SkImageFilter* filter = filters[i];
|
||||
SkBitmap result;
|
||||
SkIPoint offset;
|
||||
SkString str;
|
||||
str.printf("filter %ld", i);
|
||||
REPORTER_ASSERT_MESSAGE(reporter, filter->filterImage(&proxy, bitmap, SkMatrix::I(), &result, &offset), str.c_str());
|
||||
REPORTER_ASSERT_MESSAGE(reporter, offset.fX == 20 && offset.fY == 30, str.c_str());
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < SK_ARRAY_COUNT(filters); ++i) {
|
||||
SkSafeUnref(filters[i]);
|
||||
}
|
||||
for (size_t i = 0; i < SK_ARRAY_COUNT(filters); ++i) {
|
||||
SkSafeUnref(filters[i]);
|
||||
}
|
||||
}
|
||||
|
||||
DEF_TEST(ImageFilterCropRect, reporter) {
|
||||
SkBitmap temp;
|
||||
temp.setConfig(SkBitmap::kARGB_8888_Config, 100, 100);
|
||||
temp.allocPixels();
|
||||
SkBitmapDevice device(temp);
|
||||
test_crop_rects(&device, reporter);
|
||||
}
|
||||
|
||||
DEF_GPUTEST(ImageFilterCropRectGPU, reporter, factory) {
|
||||
GrContext* context = factory->get(static_cast<GrContextFactory::GLContextType>(0));
|
||||
SkGpuDevice device(context, SkBitmap::kARGB_8888_Config, 100, 100);
|
||||
test_crop_rects(&device, reporter);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user