aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/effects/SkMagnifierImageFilter.cpp
diff options
context:
space:
mode:
authorGravatar rmistry <rmistry@google.com>2015-04-01 15:53:13 -0700
committerGravatar Commit bot <commit-bot@chromium.org>2015-04-01 15:53:13 -0700
commit82973dbf4f22928e8dd75c8bc5b155f842c8a557 (patch)
tree151f594695f76fd06e7c4317db36891b98eed309 /src/effects/SkMagnifierImageFilter.cpp
parentfd40a249d814c3ca990422348266662a1521fb45 (diff)
Revert of Implement approx-match support in image filter saveLayer() offscreen. (patchset #31 id:590001 of https://codereview.chromium.org/1034733002/)
Reason for revert: Spoke to Stephen about this. Reverting because failing debug builds: https://uberchromegw.corp.google.com/i/client.skia/builders/Test-Mac10.9-Clang-MacMini6.2-GPU-HD4000-x86_64-Debug/builds/51 https://uberchromegw.corp.google.com/i/client.skia/builders/Test-Ubuntu-GCC-ShuttleA-GPU-GTX660-x86_64-Debug/builds/54 Original issue's description: > Implement approx-match support in image filter saveLayer() offscreen. > > Currently, the GPU-side image filter implementation creates > exact-match textures for the offscreen backing stores for > saveLayer(). This is because several filters have GPU > implementations which depend on the texture coordinates > being 0..1. > > The fix is three-fold: > > 1) Store the actual requested size in the SkGpuDevice, so > that when wrapping it in an SkBitmap for passing to > filterImage(), we can give it the original size. > 2) Fix the filters (SkMagnifierImageFilter, > SkLightingImageFilter, SkMatrixConvolutionImageFilter, > SkMatrixImageFilter) whose GPU implementation depends on > 0..1 texture coordinates. > 3) Remove the exception for GPU-side image filters in > SkCanvas::internalSaveLayer(). > > For the lighting filters, there were two bugs which were > cancelling each other out: the sobel filter matrix was > being computed upside down, but then we'd negate the > resulting normal. This worked fine in the exact-match case, > but in the approx-match case we'd sample garbage along > the edge pixels. Also, we never implemented the edge pixels > according to spec in the GPU case. It requires a > different fragment shader for each edge of the nine-patch, > which meant we couldn't use asFragmentProcessor(), and had > to implement the drawing via a filterImageGPU() override. > In order to avoid polluting the public API, I inserted a > new base class, SkLightingImageFilterInternal above > Sk[Diffuse|Specular]LightingImageFilter to handle the > implementation. > > For the SkMatrixConvolutionImageFilter, it seems the > GLSL clamp() function occasionally returns values outside > the clamped range, resulting in access of garbage > texels even in GL_NEAREST. The fix here is to clamp to a > rect inset by half a texel. There was also a bug in > the unpremultiply step when fConvolveAlpha is false. > > For SkMatrixImageFilter, the fix was to make the generic > draw path be more careful about when to use texture domain. > If the bitmap already has a texture, use texture domain > if the srcRect is smaller than the entire texture (not > the entire bitmap). > > N.B.: this change will cause some minor pixel diffs in the > GPU results of the following GMs (and possibly more): > matriximagefilter, matrixconvolution, imagefiltersscaled, > lighting, imagemagnifier, filterfastbounds, > complexclip_aa_Layer_invert, complexclip_aa_layer, > complexclip_bw_layer_invert, complexclip_bw_layer. > > BUG=skia:3532 > > Committed: https://skia.googlesource.com/skia/+/b97dafefe63ea0a1bbce8e8b209f4920983fb8b9 > > Committed: https://skia.googlesource.com/skia/+/f5f8518fe0bbd2703e4ffc1b11ad7b4312ff7641 > > Committed: https://skia.googlesource.com/skia/+/46112cf2a7c7307f1c9eebb5f881cbda15aa460c TBR=bsalomon@google.com,reed@chromium.org,senorblanco@chromium.org NOPRESUBMIT=true NOTREECHECKS=true NOTRY=true BUG=skia:3532 Review URL: https://codereview.chromium.org/1057693002
Diffstat (limited to 'src/effects/SkMagnifierImageFilter.cpp')
-rw-r--r--src/effects/SkMagnifierImageFilter.cpp51
1 files changed, 11 insertions, 40 deletions
diff --git a/src/effects/SkMagnifierImageFilter.cpp b/src/effects/SkMagnifierImageFilter.cpp
index 6d2ee01d52..622713d796 100644
--- a/src/effects/SkMagnifierImageFilter.cpp
+++ b/src/effects/SkMagnifierImageFilter.cpp
@@ -25,7 +25,6 @@ class GrMagnifierEffect : public GrSingleTextureEffect {
public:
static GrFragmentProcessor* Create(GrTexture* texture,
- const SkRect& bounds,
float xOffset,
float yOffset,
float xInvZoom,
@@ -33,7 +32,6 @@ public:
float xInvInset,
float yInvInset) {
return SkNEW_ARGS(GrMagnifierEffect, (texture,
- bounds,
xOffset,
yOffset,
xInvZoom,
@@ -50,22 +48,15 @@ public:
GrGLFragmentProcessor* createGLInstance() const override;
- const SkRect& bounds() const { return fBounds; } // Bounds of source image.
- // Offset to apply to zoomed pixels, (srcRect position / texture size).
float x_offset() const { return fXOffset; }
float y_offset() const { return fYOffset; }
-
- // Scale to apply to zoomed pixels (srcRect size / bounds size).
float x_inv_zoom() const { return fXInvZoom; }
float y_inv_zoom() const { return fYInvZoom; }
-
- // 1/radius over which to transition from unzoomed to zoomed pixels (bounds size / inset).
float x_inv_inset() const { return fXInvInset; }
float y_inv_inset() const { return fYInvInset; }
private:
GrMagnifierEffect(GrTexture* texture,
- const SkRect& bounds,
float xOffset,
float yOffset,
float xInvZoom,
@@ -73,7 +64,6 @@ private:
float xInvInset,
float yInvInset)
: GrSingleTextureEffect(texture, GrCoordTransform::MakeDivByTextureWHMatrix(texture))
- , fBounds(bounds)
, fXOffset(xOffset)
, fYOffset(yOffset)
, fXInvZoom(xInvZoom)
@@ -89,7 +79,6 @@ private:
GR_DECLARE_FRAGMENT_PROCESSOR_TEST;
- SkRect fBounds;
float fXOffset;
float fYOffset;
float fXInvZoom;
@@ -120,7 +109,6 @@ private:
UniformHandle fOffsetVar;
UniformHandle fInvZoomVar;
UniformHandle fInvInsetVar;
- UniformHandle fBoundsVar;
typedef GrGLFragmentProcessor INHERITED;
};
@@ -146,10 +134,6 @@ void GrGLMagnifierEffect::emitCode(GrGLFPBuilder* builder,
GrGLProgramBuilder::kFragment_Visibility |
GrGLProgramBuilder::kVertex_Visibility,
kVec2f_GrSLType, kDefault_GrSLPrecision, "InvInset");
- fBoundsVar = builder->addUniform(
- GrGLProgramBuilder::kFragment_Visibility |
- GrGLProgramBuilder::kVertex_Visibility,
- kVec4f_GrSLType, kDefault_GrSLPrecision, "Bounds");
GrGLFPFragmentBuilder* fsBuilder = builder->getFragmentShaderBuilder();
SkString coords2D = fsBuilder->ensureFSCoords2D(coords, 0);
@@ -158,9 +142,9 @@ void GrGLMagnifierEffect::emitCode(GrGLFPBuilder* builder,
builder->getUniformCStr(fOffsetVar),
coords2D.c_str(),
builder->getUniformCStr(fInvZoomVar));
- const char* bounds = builder->getUniformCStr(fBoundsVar);
- fsBuilder->codeAppendf("\t\tvec2 delta = (coord - %s.xy) * %s.zw;\n", bounds, bounds);
- fsBuilder->codeAppendf("\t\tdelta = min(delta, vec2(1.0, 1.0) - delta);\n");
+
+ fsBuilder->codeAppend("\t\tvec2 delta = min(coord, vec2(1.0, 1.0) - coord);\n");
+
fsBuilder->codeAppendf("\t\tdelta = delta * %s;\n", builder->getUniformCStr(fInvInsetVar));
fsBuilder->codeAppend("\t\tfloat weight = 0.0;\n");
@@ -191,8 +175,6 @@ void GrGLMagnifierEffect::setData(const GrGLProgramDataManager& pdman,
pdman.set2f(fOffsetVar, zoom.x_offset(), zoom.y_offset());
pdman.set2f(fInvZoomVar, zoom.x_inv_zoom(), zoom.y_inv_zoom());
pdman.set2f(fInvInsetVar, zoom.x_inv_inset(), zoom.y_inv_inset());
- pdman.set4f(fBoundsVar, zoom.bounds().x(), zoom.bounds().y(),
- zoom.bounds().width(), zoom.bounds().height());
}
/////////////////////////////////////////////////////////////////////
@@ -224,7 +206,6 @@ GrFragmentProcessor* GrMagnifierEffect::TestCreate(SkRandom* random,
GrFragmentProcessor* effect = GrMagnifierEffect::Create(
texture,
- SkRect::MakeWH(SkIntToScalar(kMaxWidth), SkIntToScalar(kMaxHeight)),
(float) width / texture->width(),
(float) height / texture->height(),
texture->width() / (float) x,
@@ -239,8 +220,7 @@ GrFragmentProcessor* GrMagnifierEffect::TestCreate(SkRandom* random,
bool GrMagnifierEffect::onIsEqual(const GrFragmentProcessor& sBase) const {
const GrMagnifierEffect& s = sBase.cast<GrMagnifierEffect>();
- return (this->fBounds == s.fBounds &&
- this->fXOffset == s.fXOffset &&
+ return (this->fXOffset == s.fXOffset &&
this->fYOffset == s.fYOffset &&
this->fXInvZoom == s.fXInvZoom &&
this->fYInvZoom == s.fYInvZoom &&
@@ -278,27 +258,18 @@ SkMagnifierImageFilter::SkMagnifierImageFilter(const SkRect& srcRect, SkScalar i
#if SK_SUPPORT_GPU
bool SkMagnifierImageFilter::asFragmentProcessor(GrFragmentProcessor** fp, GrTexture* texture,
- const SkMatrix&, const SkIRect&bounds) const {
+ const SkMatrix&, const SkIRect&) const {
if (fp) {
- SkScalar yOffset = texture->origin() == kTopLeft_GrSurfaceOrigin ? fSrcRect.y() :
- texture->height() - fSrcRect.height() * texture->height() / bounds.height()
- - fSrcRect.y();
- int boundsY = (texture->origin() == kTopLeft_GrSurfaceOrigin) ? bounds.y() :
- (texture->height() - bounds.height());
- SkRect effectBounds = SkRect::MakeXYWH(
- SkIntToScalar(bounds.x()) / texture->width(),
- SkIntToScalar(boundsY) / texture->height(),
- SkIntToScalar(texture->width()) / bounds.width(),
- SkIntToScalar(texture->height()) / bounds.height());
+ SkScalar yOffset = (texture->origin() == kTopLeft_GrSurfaceOrigin) ? fSrcRect.y() :
+ (texture->height() - (fSrcRect.y() + fSrcRect.height()));
SkScalar invInset = fInset > 0 ? SkScalarInvert(fInset) : SK_Scalar1;
*fp = GrMagnifierEffect::Create(texture,
- effectBounds,
fSrcRect.x() / texture->width(),
yOffset / texture->height(),
- fSrcRect.width() / bounds.width(),
- fSrcRect.height() / bounds.height(),
- bounds.width() * invInset,
- bounds.height() * invInset);
+ fSrcRect.width() / texture->width(),
+ fSrcRect.height() / texture->height(),
+ texture->width() * invInset,
+ texture->height() * invInset);
}
return true;
}