aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar senorblanco@chromium.org <senorblanco@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81>2011-07-22 15:31:14 +0000
committerGravatar senorblanco@chromium.org <senorblanco@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81>2011-07-22 15:31:14 +0000
commit2ce9a04b27f29d618e70a9b6ae535e17d73910e0 (patch)
tree16d364f70d850387d40b81a0fd1f9d490a3c2924
parent58007d713eb1d408cc9a2b9cf37ae95bdbea9e38 (diff)
Improve GPU blur performance by clearing only when necessary. This gives a
1.8X speedup on the Blurs sample, and 2.3X on the BigBlur sample. We don't need to clear while downsampling, since each step reads only the pixels written in the previous step. We can avoid destination clears before convolution by disabling blending. We also don't need to clear when upsampling, since the upsample step also only reads pixels written by the convolution. The only clears we then need to do are on each side of the srcRect used for convolution, and a 1-pixel border for bilinear upsampling. Since our srcRect is always offset to (0, 0), we only need to clear on the right and bottom. Review URL: http://codereview.appspot.com/4803048/ git-svn-id: http://skia.googlecode.com/svn/trunk@1941 2bbb7eff-a529-9590-31e7-b0007b416f81
-rw-r--r--gpu/src/GrContext.cpp1
-rw-r--r--src/gpu/SkGpuDevice.cpp31
2 files changed, 22 insertions, 10 deletions
diff --git a/gpu/src/GrContext.cpp b/gpu/src/GrContext.cpp
index ef5ad1157d..b829323b2e 100644
--- a/gpu/src/GrContext.cpp
+++ b/gpu/src/GrContext.cpp
@@ -1736,5 +1736,6 @@ void GrContext::convolve(GrTexture* texture,
fGpu->setSamplerState(0, sampler);
fGpu->setViewMatrix(GrMatrix::I());
fGpu->setTexture(0, texture);
+ fGpu->setBlendFunc(kOne_BlendCoeff, kZero_BlendCoeff);
fGpu->drawSimpleRect(rect, NULL, 1 << 0);
}
diff --git a/src/gpu/SkGpuDevice.cpp b/src/gpu/SkGpuDevice.cpp
index c4e0ebecd1..45dac336ea 100644
--- a/src/gpu/SkGpuDevice.cpp
+++ b/src/gpu/SkGpuDevice.cpp
@@ -913,9 +913,7 @@ static bool drawWithGPUMaskFilter(GrContext* context, const SkPath& path,
GrClip oldClip = context->getClip();
context->setRenderTarget(dstTexture->asRenderTarget());
context->setClip(srcRect);
- // FIXME: could just clear bounds
context->clear(NULL, 0);
- GrMatrix transM;
GrPaint tempPaint;
tempPaint.reset();
@@ -959,9 +957,6 @@ static bool drawWithGPUMaskFilter(GrContext* context, const SkPath& path,
context->setRenderTarget(dstTexture->asRenderTarget());
SkRect dstRect(srcRect);
scaleRect(&dstRect, 0.5f);
- // Clear out 1 pixel border for linear filtering.
- // FIXME: for now, clear everything
- context->clear(NULL, 0);
paint.setTexture(0, srcTexture);
context->drawRectToRect(paint, dstRect, srcRect);
srcRect = dstRect;
@@ -972,25 +967,41 @@ static bool drawWithGPUMaskFilter(GrContext* context, const SkPath& path,
float* kernel = kernelStorage.get();
buildKernel(sigma, kernel, kernelWidth);
+ // Clear out a halfWidth to the right of the srcRect to prevent the
+ // X convolution from reading garbage.
+ SkIRect clearRect = SkIRect::MakeXYWH(
+ srcRect.fRight, srcRect.fTop, halfWidth, srcRect.height());
+ context->clear(&clearRect, 0x0);
+
context->setRenderTarget(dstTexture->asRenderTarget());
- context->clear(NULL, 0);
context->convolveInX(srcTexture, srcRect, kernel, kernelWidth);
SkTSwap(srcTexture, dstTexture);
+ // Clear out a halfWidth below the srcRect to prevent the Y
+ // convolution from reading garbage.
+ clearRect = SkIRect::MakeXYWH(
+ srcRect.fLeft, srcRect.fBottom, srcRect.width(), halfWidth);
+ context->clear(&clearRect, 0x0);
+
context->setRenderTarget(dstTexture->asRenderTarget());
- context->clear(NULL, 0);
context->convolveInY(srcTexture, srcRect, kernel, kernelWidth);
SkTSwap(srcTexture, dstTexture);
+ // Clear one pixel to the right and below, to accommodate bilinear
+ // upsampling.
+ clearRect = SkIRect::MakeXYWH(
+ srcRect.fLeft, srcRect.fBottom, srcRect.width() + 1, 1);
+ context->clear(&clearRect, 0x0);
+ clearRect = SkIRect::MakeXYWH(
+ srcRect.fRight, srcRect.fTop, 1, srcRect.height());
+ context->clear(&clearRect, 0x0);
+
if (scaleFactor > 1) {
// FIXME: This should be mitchell, not bilinear.
paint.getTextureSampler(0)->setFilter(GrSamplerState::kBilinear_Filter);
sampleM.setIDiv(srcTexture->width(), srcTexture->height());
paint.getTextureSampler(0)->setMatrix(sampleM);
context->setRenderTarget(dstTexture->asRenderTarget());
- // Clear out 2 pixel border for bicubic filtering.
- // FIXME: for now, clear everything
- context->clear(NULL, 0);
paint.setTexture(0, srcTexture);
SkRect dstRect(srcRect);
scaleRect(&dstRect, scaleFactor);