aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorGravatar senorblanco <senorblanco@chromium.org>2016-01-19 08:50:18 -0800
committerGravatar Commit bot <commit-bot@chromium.org>2016-01-19 08:50:18 -0800
commit1ea67a31c527f4d5d77c59a3ea3a12e39308e8c5 (patch)
tree32b1a746746a8581fa27eac2c932ce51e9ed1808 /src
parentb6474dd1a530a543ae799c3822e8bc60180761c0 (diff)
Fix SkAlphaThresholdFilter bounds handling.
SkAlphaThresholdFilter was always allocating a mask texture of the same size as the source texture. In addition to potentially wasting VRAM, this could cause the mask to be offset from the source texture, if the resulting bounds were a different size than the source texture. The fix is to allocate a mask texture only as large as the bounds, and to offset it to the bounds origin on draw. BUG=skia: GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1609573002 Review URL: https://codereview.chromium.org/1609573002
Diffstat (limited to 'src')
-rw-r--r--src/effects/SkAlphaThresholdFilter.cpp43
1 files changed, 33 insertions, 10 deletions
diff --git a/src/effects/SkAlphaThresholdFilter.cpp b/src/effects/SkAlphaThresholdFilter.cpp
index b6be944220..6cadbc3e51 100644
--- a/src/effects/SkAlphaThresholdFilter.cpp
+++ b/src/effects/SkAlphaThresholdFilter.cpp
@@ -68,14 +68,26 @@ SkImageFilter* SkAlphaThresholdFilter::Create(const SkRegion& region,
#include "glsl/GrGLSLProgramDataManager.h"
#include "glsl/GrGLSLUniformHandler.h"
+namespace {
+
+SkMatrix make_div_and_translate_matrix(GrTexture* texture, int x, int y) {
+ SkMatrix matrix = GrCoordTransform::MakeDivByTextureWHMatrix(texture);
+ matrix.preTranslate(SkIntToScalar(x), SkIntToScalar(y));
+ return matrix;
+}
+
+};
+
class AlphaThresholdEffect : public GrFragmentProcessor {
public:
static GrFragmentProcessor* Create(GrTexture* texture,
GrTexture* maskTexture,
float innerThreshold,
- float outerThreshold) {
- return new AlphaThresholdEffect(texture, maskTexture, innerThreshold, outerThreshold);
+ float outerThreshold,
+ const SkIRect& bounds) {
+ return new AlphaThresholdEffect(texture, maskTexture, innerThreshold, outerThreshold,
+ bounds);
}
virtual ~AlphaThresholdEffect() {};
@@ -89,7 +101,8 @@ private:
AlphaThresholdEffect(GrTexture* texture,
GrTexture* maskTexture,
float innerThreshold,
- float outerThreshold)
+ float outerThreshold,
+ const SkIRect& bounds)
: fInnerThreshold(innerThreshold)
, fOuterThreshold(outerThreshold)
, fImageCoordTransform(kLocal_GrCoordSet,
@@ -97,7 +110,8 @@ private:
GrTextureParams::kNone_FilterMode)
, fImageTextureAccess(texture)
, fMaskCoordTransform(kLocal_GrCoordSet,
- GrCoordTransform::MakeDivByTextureWHMatrix(maskTexture), maskTexture,
+ make_div_and_translate_matrix(maskTexture, -bounds.x(), -bounds.y()),
+ maskTexture,
GrTextureParams::kNone_FilterMode)
, fMaskTextureAccess(maskTexture) {
this->initClassID<AlphaThresholdEffect>();
@@ -205,7 +219,14 @@ const GrFragmentProcessor* AlphaThresholdEffect::TestCreate(GrProcessorTestData*
GrTexture* maskTex = d->fTextures[GrProcessorUnitTest::kAlphaTextureIdx];
float innerThresh = d->fRandom->nextUScalar1();
float outerThresh = d->fRandom->nextUScalar1();
- return AlphaThresholdEffect::Create(bmpTex, maskTex, innerThresh, outerThresh);
+ const int kMaxWidth = 1000;
+ const int kMaxHeight = 1000;
+ uint32_t width = d->fRandom->nextULessThan(kMaxWidth);
+ uint32_t height = d->fRandom->nextULessThan(kMaxHeight);
+ uint32_t x = d->fRandom->nextULessThan(kMaxWidth - width);
+ uint32_t y = d->fRandom->nextULessThan(kMaxHeight - height);
+ SkIRect bounds = SkIRect::MakeXYWH(x, y, width, height);
+ return AlphaThresholdEffect::Create(bmpTex, maskTex, innerThresh, outerThresh, bounds);
}
///////////////////////////////////////////////////////////////////////////////
@@ -260,7 +281,7 @@ SkAlphaThresholdFilterImpl::SkAlphaThresholdFilterImpl(const SkRegion& region,
bool SkAlphaThresholdFilterImpl::asFragmentProcessor(GrFragmentProcessor** fp,
GrTexture* texture,
const SkMatrix& inMatrix,
- const SkIRect&) const {
+ const SkIRect& bounds) const {
if (fp) {
GrContext* context = texture->getContext();
GrSurfaceDesc maskDesc;
@@ -272,8 +293,8 @@ bool SkAlphaThresholdFilterImpl::asFragmentProcessor(GrFragmentProcessor** fp,
maskDesc.fFlags = kRenderTarget_GrSurfaceFlag;
// Add one pixel of border to ensure that clamp mode will be all zeros
// the outside.
- maskDesc.fWidth = texture->width();
- maskDesc.fHeight = texture->height();
+ maskDesc.fWidth = bounds.width();
+ maskDesc.fHeight = bounds.height();
SkAutoTUnref<GrTexture> maskTexture(
context->textureProvider()->createApproxTexture(maskDesc));
if (!maskTexture) {
@@ -288,9 +309,10 @@ bool SkAlphaThresholdFilterImpl::asFragmentProcessor(GrFragmentProcessor** fp,
SkRegion::Iterator iter(fRegion);
drawContext->clear(nullptr, 0x0, true);
+ GrClip clip(SkRect::Make(SkIRect::MakeWH(bounds.width(), bounds.height())));
while (!iter.done()) {
SkRect rect = SkRect::Make(iter.rect());
- drawContext->drawRect(GrClip::WideOpen(), grPaint, inMatrix, rect);
+ drawContext->drawRect(clip, grPaint, inMatrix, rect);
iter.next();
}
}
@@ -298,7 +320,8 @@ bool SkAlphaThresholdFilterImpl::asFragmentProcessor(GrFragmentProcessor** fp,
*fp = AlphaThresholdEffect::Create(texture,
maskTexture,
fInnerThreshold,
- fOuterThreshold);
+ fOuterThreshold,
+ bounds);
}
return true;
}