From 06d3d682b4d26fb390c38ab2bb76853fd6e29be2 Mon Sep 17 00:00:00 2001 From: senorblanco Date: Sat, 28 Mar 2015 14:50:05 -0700 Subject: [PATCH] Revert "Implement approx-match support in image filter saveLayer() offscreen." This reverts commit b97dafefe63ea0a1bbce8e8b209f4920983fb8b9. SkLightingImageFilter boundaries are incorrect (see GM:lighting). BUG=skia: TBR= Review URL: https://codereview.chromium.org/1048583002 --- src/core/SkCanvas.cpp | 8 ++++++ src/effects/SkMagnifierImageFilter.cpp | 46 ++++++++-------------------------- src/gpu/SkGpuDevice.cpp | 34 +++++++++---------------- src/gpu/SkGpuDevice.h | 13 +++------- 4 files changed, 34 insertions(+), 67 deletions(-) diff --git a/src/core/SkCanvas.cpp b/src/core/SkCanvas.cpp index 5310c9f..8426f09 100644 --- a/src/core/SkCanvas.cpp +++ b/src/core/SkCanvas.cpp @@ -936,6 +936,14 @@ void SkCanvas::internalSaveLayer(const SkRect* bounds, const SkPaint* paint, Sav } SkBaseDevice::TileUsage usage = SkBaseDevice::kNever_TileUsage; +#if 1 + // this seems needed for current GMs, but makes us draw slower on the GPU + // Related to https://code.google.com/p/skia/issues/detail?id=3519 ? + // + if (paint && paint->getImageFilter()) { + usage = SkBaseDevice::kPossible_TileUsage; + } +#endif device = device->onCreateDevice(SkBaseDevice::CreateInfo(info, usage, geo), paint); if (NULL == device) { SkErrorInternals::SetError( kInternalError_SkError, diff --git a/src/effects/SkMagnifierImageFilter.cpp b/src/effects/SkMagnifierImageFilter.cpp index d8e21cf..622713d 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,7 +48,6 @@ public: GrGLFragmentProcessor* createGLInstance() const override; - const SkRect& bounds() const { return fBounds; } float x_offset() const { return fXOffset; } float y_offset() const { return fYOffset; } float x_inv_zoom() const { return fXInvZoom; } @@ -60,7 +57,6 @@ public: private: GrMagnifierEffect(GrTexture* texture, - const SkRect& bounds, float xOffset, float yOffset, float xInvZoom, @@ -68,7 +64,6 @@ private: float xInvInset, float yInvInset) : GrSingleTextureEffect(texture, GrCoordTransform::MakeDivByTextureWHMatrix(texture)) - , fBounds(bounds) , fXOffset(xOffset) , fYOffset(yOffset) , fXInvZoom(xInvZoom) @@ -84,7 +79,6 @@ private: GR_DECLARE_FRAGMENT_PROCESSOR_TEST; - SkRect fBounds; float fXOffset; float fYOffset; float fXInvZoom; @@ -115,7 +109,6 @@ private: UniformHandle fOffsetVar; UniformHandle fInvZoomVar; UniformHandle fInvInsetVar; - UniformHandle fBoundsVar; typedef GrGLFragmentProcessor INHERITED; }; @@ -141,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); @@ -153,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"); @@ -186,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()); } ///////////////////////////////////////////////////////////////////// @@ -219,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, @@ -234,8 +220,7 @@ GrFragmentProcessor* GrMagnifierEffect::TestCreate(SkRandom* random, bool GrMagnifierEffect::onIsEqual(const GrFragmentProcessor& sBase) const { const GrMagnifierEffect& s = sBase.cast(); - 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 && @@ -273,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; } diff --git a/src/gpu/SkGpuDevice.cpp b/src/gpu/SkGpuDevice.cpp index 021cfba..38a22e6 100644 --- a/src/gpu/SkGpuDevice.cpp +++ b/src/gpu/SkGpuDevice.cpp @@ -121,15 +121,10 @@ public: /////////////////////////////////////////////////////////////////////////////// SkGpuDevice* SkGpuDevice::Create(GrRenderTarget* rt, const SkSurfaceProps* props, unsigned flags) { - return SkGpuDevice::Create(rt, rt->width(), rt->height(), props, flags); -} - -SkGpuDevice* SkGpuDevice::Create(GrRenderTarget* rt, int width, int height, - const SkSurfaceProps* props, unsigned flags) { if (!rt || rt->wasDestroyed()) { return NULL; } - return SkNEW_ARGS(SkGpuDevice, (rt, width, height, props, flags)); + return SkNEW_ARGS(SkGpuDevice, (rt, props, flags)); } static SkDeviceProperties surfaceprops_to_deviceprops(const SkSurfaceProps* props) { @@ -148,8 +143,7 @@ static SkSurfaceProps copy_or_default_props(const SkSurfaceProps* props) { } } -SkGpuDevice::SkGpuDevice(GrRenderTarget* rt, int width, int height, - const SkSurfaceProps* props, unsigned flags) +SkGpuDevice::SkGpuDevice(GrRenderTarget* rt, const SkSurfaceProps* props, unsigned flags) : INHERITED(surfaceprops_to_deviceprops(props)) , fSurfaceProps(copy_or_default_props(props)) { @@ -160,7 +154,7 @@ SkGpuDevice::SkGpuDevice(GrRenderTarget* rt, int width, int height, fRenderTarget = SkRef(rt); - SkImageInfo info = rt->surfacePriv().info().makeWH(width, height); + SkImageInfo info = rt->surfacePriv().info(); SkPixelRef* pr = SkNEW_ARGS(SkGrPixelRef, (info, rt)); fLegacyBitmap.setInfo(info); fLegacyBitmap.setPixelRef(pr)->unref(); @@ -217,7 +211,7 @@ SkGpuDevice* SkGpuDevice::Create(GrContext* context, SkSurface::Budgeted budgete return NULL; } - return SkNEW_ARGS(SkGpuDevice, (rt, info.width(), info.height(), props, flags)); + return SkNEW_ARGS(SkGpuDevice, (rt, props, flags)); } SkGpuDevice::~SkGpuDevice() { @@ -742,9 +736,9 @@ GrTexture* create_mask_GPU(GrContext* context, return mask; } -SkBitmap wrap_texture(GrTexture* texture, int width, int height) { +SkBitmap wrap_texture(GrTexture* texture) { SkBitmap result; - result.setInfo(SkImageInfo::MakeN32Premul(width, height)); + result.setInfo(texture->surfacePriv().info()); result.setPixelRef(SkNEW_ARGS(SkGrPixelRef, (result.info(), texture)))->unref(); return result; } @@ -1480,7 +1474,6 @@ void SkGpuDevice::internalDrawBitmap(const SkBitmap& bitmap, } bool SkGpuDevice::filterTexture(GrContext* context, GrTexture* texture, - int width, int height, const SkImageFilter* filter, const SkImageFilter::Context& ctx, SkBitmap* result, SkIPoint* offset) { @@ -1491,8 +1484,7 @@ bool SkGpuDevice::filterTexture(GrContext* context, GrTexture* texture, SkDeviceImageFilterProxy proxy(this, SkSurfaceProps(0, getLeakyProperties().pixelGeometry())); if (filter->canFilterImageGPU()) { - return filter->filterImageGPU(&proxy, wrap_texture(texture, width, height), - ctx, result, offset); + return filter->filterImageGPU(&proxy, wrap_texture(texture), ctx, result, offset); } else { return false; } @@ -1531,7 +1523,7 @@ void SkGpuDevice::drawSprite(const SkDraw& draw, const SkBitmap& bitmap, // This cache is transient, and is freed (along with all its contained // textures) when it goes out of scope. SkImageFilter::Context ctx(matrix, clipBounds, cache); - if (this->filterTexture(fContext, texture, w, h, filter, ctx, &filteredBitmap, + if (this->filterTexture(fContext, texture, filter, ctx, &filteredBitmap, &offset)) { texture = (GrTexture*) filteredBitmap.getTexture(); w = filteredBitmap.width(); @@ -1645,8 +1637,8 @@ void SkGpuDevice::drawDevice(const SkDraw& draw, SkBaseDevice* device, // textures) when it goes out of scope. SkAutoTUnref cache(getImageFilterCache()); SkImageFilter::Context ctx(matrix, clipBounds, cache); - if (this->filterTexture(fContext, devTex, device->width(), device->height(), - filter, ctx, &filteredBitmap, &offset)) { + if (this->filterTexture(fContext, devTex, filter, ctx, &filteredBitmap, + &offset)) { devTex = filteredBitmap.getTexture(); w = filteredBitmap.width(); h = filteredBitmap.height(); @@ -1699,8 +1691,7 @@ bool SkGpuDevice::filterImage(const SkImageFilter* filter, const SkBitmap& src, // must be pushed upstack. AutoBitmapTexture abt(fContext, src, NULL, &texture); - return this->filterTexture(fContext, texture, src.width(), src.height(), - filter, ctx, result, offset); + return this->filterTexture(fContext, texture, filter, ctx, result, offset); } /////////////////////////////////////////////////////////////////////////////// @@ -1910,8 +1901,7 @@ SkBaseDevice* SkGpuDevice::onCreateDevice(const CreateInfo& cinfo, const SkPaint if (texture) { SkSurfaceProps props(fSurfaceProps.flags(), cinfo.fPixelGeometry); - return SkGpuDevice::Create( - texture->asRenderTarget(), cinfo.fInfo.width(), cinfo.fInfo.height(), &props, flags); + return SkGpuDevice::Create(texture->asRenderTarget(), &props, flags); } else { SkErrorInternals::SetError( kInternalError_SkError, "---- failed to create compatible device texture [%d %d]\n", diff --git a/src/gpu/SkGpuDevice.h b/src/gpu/SkGpuDevice.h index 999a698..ad0c2d6 100644 --- a/src/gpu/SkGpuDevice.h +++ b/src/gpu/SkGpuDevice.h @@ -41,13 +41,6 @@ public: static SkGpuDevice* Create(GrRenderTarget* target, const SkSurfaceProps*, unsigned flags = 0); /** - * Creates an SkGpuDevice from a GrRenderTarget whose texture width/height is - * different than its actual width/height (e.g., approx-match scratch texture). - */ - static SkGpuDevice* Create(GrRenderTarget* target, int width, int height, - const SkSurfaceProps*, unsigned flags = 0); - - /** * New device that will create an offscreen renderTarget based on the ImageInfo and * sampleCount. The Budgeted param controls whether the device's backing store counts against * the resource cache budget. On failure, returns NULL. @@ -74,7 +67,7 @@ public: GrRenderTarget* accessRenderTarget() override; SkImageInfo imageInfo() const override { - return fLegacyBitmap.info(); + return fRenderTarget ? fRenderTarget->surfacePriv().info() : SkImageInfo::MakeUnknown(); } const SkSurfaceProps& surfaceProps() const { return fSurfaceProps; } @@ -128,7 +121,7 @@ public: const SkImageFilter::Context&, SkBitmap*, SkIPoint*) override; - bool filterTexture(GrContext*, GrTexture*, int width, int height, const SkImageFilter*, + bool filterTexture(GrContext*, GrTexture*, const SkImageFilter*, const SkImageFilter::Context&, SkBitmap* result, SkIPoint* offset); @@ -154,7 +147,7 @@ private: SkBitmap fLegacyBitmap; bool fNeedClear; - SkGpuDevice(GrRenderTarget*, int width, int height, const SkSurfaceProps*, unsigned flags); + SkGpuDevice(GrRenderTarget*, const SkSurfaceProps*, unsigned flags); SkBaseDevice* onCreateDevice(const CreateInfo&, const SkPaint*) override; -- 2.7.4