diff options
24 files changed, 391 insertions, 255 deletions
diff --git a/gn/gpu.gni b/gn/gpu.gni index ca5a91975d..87e3d9b22d 100644 --- a/gn/gpu.gni +++ b/gn/gpu.gni @@ -349,10 +349,12 @@ skia_gpu_sources = [ "$_src/gpu/effects/GrEllipseEffect.h", "$_src/gpu/effects/GrGaussianConvolutionFragmentProcessor.cpp", "$_src/gpu/effects/GrGaussianConvolutionFragmentProcessor.h", - "$_src/gpu/effects/GrMatrixConvolutionEffect.cpp", - "$_src/gpu/effects/GrMatrixConvolutionEffect.h", "$_src/gpu/effects/GrLumaColorFilterEffect.cpp", "$_src/gpu/effects/GrLumaColorFilterEffect.h", + "$_src/gpu/effects/GrMagnifierEffect.cpp", + "$_src/gpu/effects/GrMagnifierEffect.h", + "$_src/gpu/effects/GrMatrixConvolutionEffect.cpp", + "$_src/gpu/effects/GrMatrixConvolutionEffect.h", "$_src/gpu/effects/GrNonlinearColorSpaceXformEffect.cpp", "$_src/gpu/effects/GrNonlinearColorSpaceXformEffect.h", "$_src/gpu/effects/GrOverdrawFragmentProcessor.cpp", diff --git a/gn/sksl.gni b/gn/sksl.gni index e40da5db82..9d992d181f 100644 --- a/gn/sksl.gni +++ b/gn/sksl.gni @@ -37,6 +37,7 @@ skia_gpu_processor_sources = [ "$_src/gpu/effects/GrDitherEffect.fp", "$_src/gpu/effects/GrEllipseEffect.fp", "$_src/gpu/effects/GrLumaColorFilterEffect.fp", + "$_src/gpu/effects/GrMagnifierEffect.fp", "$_src/gpu/effects/GrPremulInputFragmentProcessor.fp", "$_src/gpu/effects/GrRectBlurEffect.fp", "$_src/gpu/effects/GrOverdrawFragmentProcessor.fp", diff --git a/src/effects/GrAlphaThresholdFragmentProcessor.cpp b/src/effects/GrAlphaThresholdFragmentProcessor.cpp index 4a872e9c95..be7aded75b 100644 --- a/src/effects/GrAlphaThresholdFragmentProcessor.cpp +++ b/src/effects/GrAlphaThresholdFragmentProcessor.cpp @@ -23,6 +23,7 @@ inline GrFragmentProcessor::OptimizationFlags GrAlphaThresholdFragmentProcessor: #include "glsl/GrGLSLFragmentProcessor.h" #include "glsl/GrGLSLFragmentShaderBuilder.h" #include "glsl/GrGLSLProgramBuilder.h" +#include "GrTexture.h" #include "SkSLCPP.h" #include "SkSLUtil.h" class GrGLSLAlphaThresholdFragmentProcessor : public GrGLSLFragmentProcessor { diff --git a/src/effects/GrCircleBlurFragmentProcessor.cpp b/src/effects/GrCircleBlurFragmentProcessor.cpp index 962bf05f4d..bb9bff242f 100644 --- a/src/effects/GrCircleBlurFragmentProcessor.cpp +++ b/src/effects/GrCircleBlurFragmentProcessor.cpp @@ -252,6 +252,7 @@ std::unique_ptr<GrFragmentProcessor> GrCircleBlurFragmentProcessor::Make( #include "glsl/GrGLSLFragmentProcessor.h" #include "glsl/GrGLSLFragmentShaderBuilder.h" #include "glsl/GrGLSLProgramBuilder.h" +#include "GrTexture.h" #include "SkSLCPP.h" #include "SkSLUtil.h" class GrGLSLCircleBlurFragmentProcessor : public GrGLSLFragmentProcessor { @@ -296,7 +297,8 @@ private: (void)textureRadius; auto solidRadius = _outer.solidRadius(); (void)solidRadius; - UniformHandle& blurProfileSampler = fBlurProfileSamplerVar; + GrSurfaceProxy& blurProfileSamplerProxy = *_outer.textureSampler(0).proxy(); + GrTexture& blurProfileSampler = *blurProfileSamplerProxy.priv().peekTexture(); (void)blurProfileSampler; UniformHandle& circleData = fCircleDataVar; (void)circleData; diff --git a/src/effects/SkMagnifierImageFilter.cpp b/src/effects/SkMagnifierImageFilter.cpp index c5b3396c90..ff5bf3cc9b 100644 --- a/src/effects/SkMagnifierImageFilter.cpp +++ b/src/effects/SkMagnifierImageFilter.cpp @@ -23,6 +23,7 @@ #include "GrContext.h" #include "GrCoordTransform.h" #include "GrTexture.h" +#include "effects/GrMagnifierEffect.h" #include "glsl/GrGLSLFragmentProcessor.h" #include "glsl/GrGLSLFragmentShaderBuilder.h" #include "glsl/GrGLSLProgramDataManager.h" @@ -47,256 +48,6 @@ sk_sp<SkImageFilter> SkMagnifierImageFilter::Make(const SkRect& srcRect, SkScala cropRect)); } -#if SK_SUPPORT_GPU -class GrMagnifierEffect : public GrFragmentProcessor { -public: - static std::unique_ptr<GrFragmentProcessor> Make(sk_sp<GrTextureProxy> proxy, - const SkIRect& bounds, - const SkRect& srcRect, - float xInvZoom, - float yInvZoom, - float xInvInset, - float yInvInset) { - return std::unique_ptr<GrFragmentProcessor>( - new GrMagnifierEffect(std::move(proxy), bounds, srcRect, xInvZoom, yInvZoom, - xInvInset, yInvInset)); - } - - ~GrMagnifierEffect() override {} - - const char* name() const override { return "Magnifier"; } - - std::unique_ptr<GrFragmentProcessor> clone() const override { - return std::unique_ptr<GrFragmentProcessor>(new GrMagnifierEffect(*this)); - } - - SkString dumpInfo() const override { - SkString str; - str.appendf("Texture: %d", fTextureSampler.proxy()->uniqueID().asUInt()); - return str; - } - - const SkIRect& bounds() const { return fBounds; } // Bounds of source image. - const SkRect& srcRect() const { return fSrcRect; } - - // Scale to apply to zoomed pixels (srcRect size / bounds size). - float xInvZoom() const { return fXInvZoom; } - float yInvZoom() const { return fYInvZoom; } - - // 1/radius over which to transition from unzoomed to zoomed pixels (bounds size / inset). - float xInvInset() const { return fXInvInset; } - float yInvInset() const { return fYInvInset; } - -private: - GrMagnifierEffect(sk_sp<GrTextureProxy> proxy, - const SkIRect& bounds, - const SkRect& srcRect, - float xInvZoom, - float yInvZoom, - float xInvInset, - float yInvInset) - : INHERITED{kGrMagnifierEffect_ClassID, - ModulateByConfigOptimizationFlags(proxy->config())} - // TODO: no GrSamplerState::Filter::kBilerp? - , fCoordTransform(proxy.get()) - , fTextureSampler(std::move(proxy)) - , fBounds(bounds) - , fSrcRect(srcRect) - , fXInvZoom(xInvZoom) - , fYInvZoom(yInvZoom) - , fXInvInset(xInvInset) - , fYInvInset(yInvInset) { - this->addCoordTransform(&fCoordTransform); - this->addTextureSampler(&fTextureSampler); - } - - explicit GrMagnifierEffect(const GrMagnifierEffect& that) - : INHERITED(kGrMagnifierEffect_ClassID, that.optimizationFlags()) - , fCoordTransform(that.fCoordTransform) - , fTextureSampler(that.fTextureSampler) - , fBounds(that.fBounds) - , fSrcRect(that.fSrcRect) - , fXInvZoom(that.fXInvZoom) - , fYInvZoom(that.fYInvZoom) - , fXInvInset(that.fXInvInset) - , fYInvInset(that.fYInvInset) { - this->addCoordTransform(&fCoordTransform); - this->addTextureSampler(&fTextureSampler); - } - - GrGLSLFragmentProcessor* onCreateGLSLInstance() const override; - - void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override; - - bool onIsEqual(const GrFragmentProcessor&) const override; - - GR_DECLARE_FRAGMENT_PROCESSOR_TEST - - GrCoordTransform fCoordTransform; - TextureSampler fTextureSampler; - SkIRect fBounds; - SkRect fSrcRect; - float fXInvZoom; - float fYInvZoom; - float fXInvInset; - float fYInvInset; - - typedef GrFragmentProcessor INHERITED; -}; - -// For brevity -typedef GrGLSLProgramDataManager::UniformHandle UniformHandle; - -class GrGLMagnifierEffect : public GrGLSLFragmentProcessor { -public: - void emitCode(EmitArgs&) override; - - static inline void GenKey(const GrProcessor&, const GrShaderCaps&, GrProcessorKeyBuilder*) {} - -protected: - void onSetData(const GrGLSLProgramDataManager&, const GrFragmentProcessor&) override; - -private: - UniformHandle fOffsetVar; - UniformHandle fInvZoomVar; - UniformHandle fInvInsetVar; - UniformHandle fBoundsVar; - - typedef GrGLSLFragmentProcessor INHERITED; -}; - -void GrGLMagnifierEffect::emitCode(EmitArgs& args) { - GrGLSLUniformHandler* uniformHandler = args.fUniformHandler; - fOffsetVar = uniformHandler->addUniform(kFragment_GrShaderFlag, - kHalf2_GrSLType, "Offset"); - fInvZoomVar = uniformHandler->addUniform(kFragment_GrShaderFlag, - kHalf2_GrSLType, "InvZoom"); - fInvInsetVar = uniformHandler->addUniform(kFragment_GrShaderFlag, - kHalf2_GrSLType, "InvInset"); - fBoundsVar = uniformHandler->addUniform(kFragment_GrShaderFlag, - kHalf4_GrSLType, "Bounds"); - - GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder; - SkString coords2D = fragBuilder->ensureCoords2D(args.fTransformedCoords[0]); - fragBuilder->codeAppendf("\t\tfloat2 coord = %s;\n", coords2D.c_str()); - fragBuilder->codeAppendf("\t\tfloat2 zoom_coord = %s + %s * %s;\n", - uniformHandler->getUniformCStr(fOffsetVar), - coords2D.c_str(), - uniformHandler->getUniformCStr(fInvZoomVar)); - const char* bounds = uniformHandler->getUniformCStr(fBoundsVar); - fragBuilder->codeAppendf("\t\tfloat2 delta = (coord - %s.xy) * %s.zw;\n", bounds, bounds); - fragBuilder->codeAppendf("\t\tdelta = min(delta, half2(1.0, 1.0) - delta);\n"); - fragBuilder->codeAppendf("\t\tdelta = delta * %s;\n", - uniformHandler->getUniformCStr(fInvInsetVar)); - - fragBuilder->codeAppend("\t\thalf weight = 0.0;\n"); - fragBuilder->codeAppend("\t\tif (delta.s < 2.0 && delta.t < 2.0) {\n"); - fragBuilder->codeAppend("\t\t\tdelta = half2(2.0, 2.0) - delta;\n"); - fragBuilder->codeAppend("\t\t\thalf dist = length(delta);\n"); - fragBuilder->codeAppend("\t\t\tdist = max(2.0 - dist, 0.0);\n"); - fragBuilder->codeAppend("\t\t\tweight = min(dist * dist, 1.0);\n"); - fragBuilder->codeAppend("\t\t} else {\n"); - fragBuilder->codeAppend("\t\t\tfloat2 delta_squared = delta * delta;\n"); - fragBuilder->codeAppend("\t\t\tweight = min(min(delta_squared.x, delta_squared.y), 1.0);\n"); - fragBuilder->codeAppend("\t\t}\n"); - - fragBuilder->codeAppend("\t\tfloat2 mix_coord = mix(coord, zoom_coord, weight);\n"); - fragBuilder->codeAppend("\t\thalf4 output_color = "); - fragBuilder->appendTextureLookup(args.fTexSamplers[0], "mix_coord", kHalf2_GrSLType); - fragBuilder->codeAppend(";\n"); - - fragBuilder->codeAppendf("\t\t%s = output_color;\n", args.fOutputColor); - fragBuilder->codeAppendf("%s *= %s;\n", args.fOutputColor, args.fInputColor); -} - -void GrGLMagnifierEffect::onSetData(const GrGLSLProgramDataManager& pdman, - const GrFragmentProcessor& effect) { - const GrMagnifierEffect& zoom = effect.cast<GrMagnifierEffect>(); - - GrSurfaceProxy* proxy = zoom.textureSampler(0).proxy(); - GrTexture* tex = proxy->priv().peekTexture(); - - SkScalar invW = 1.0f / tex->width(); - SkScalar invH = 1.0f / tex->height(); - - { - SkScalar y = zoom.srcRect().y() * invH; - if (proxy->origin() != kTopLeft_GrSurfaceOrigin) { - y = 1.0f - (zoom.srcRect().height() / zoom.bounds().height()) - y; - } - - pdman.set2f(fOffsetVar, zoom.srcRect().x() * invW, y); - } - - pdman.set2f(fInvZoomVar, zoom.xInvZoom(), zoom.yInvZoom()); - pdman.set2f(fInvInsetVar, zoom.xInvInset(), zoom.yInvInset()); - - { - SkScalar y = zoom.bounds().y() * invH; - if (proxy->origin() != kTopLeft_GrSurfaceOrigin) { - y = 1.0f - zoom.bounds().height() * invH; - } - - pdman.set4f(fBoundsVar, - zoom.bounds().x() * invW, - y, - SkIntToScalar(tex->width()) / zoom.bounds().width(), - SkIntToScalar(tex->height()) / zoom.bounds().height()); - } -} - -///////////////////////////////////////////////////////////////////// - -void GrMagnifierEffect::onGetGLSLProcessorKey(const GrShaderCaps& caps, - GrProcessorKeyBuilder* b) const { - GrGLMagnifierEffect::GenKey(*this, caps, b); -} - -GrGLSLFragmentProcessor* GrMagnifierEffect::onCreateGLSLInstance() const { - return new GrGLMagnifierEffect; -} - -GR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrMagnifierEffect); - -#if GR_TEST_UTILS -std::unique_ptr<GrFragmentProcessor> GrMagnifierEffect::TestCreate(GrProcessorTestData* d) { - sk_sp<GrTextureProxy> proxy = d->textureProxy(0); - const int kMaxWidth = 200; - const int kMaxHeight = 200; - const SkScalar kMaxInset = 20.0f; - uint32_t width = d->fRandom->nextULessThan(kMaxWidth); - uint32_t height = d->fRandom->nextULessThan(kMaxHeight); - SkScalar inset = d->fRandom->nextRangeScalar(1.0f, kMaxInset); - - SkIRect bounds = SkIRect::MakeWH(SkIntToScalar(kMaxWidth), SkIntToScalar(kMaxHeight)); - SkRect srcRect = SkRect::MakeWH(SkIntToScalar(width), SkIntToScalar(height)); - - auto effect = GrMagnifierEffect::Make(std::move(proxy), - bounds, - srcRect, - srcRect.width() / bounds.width(), - srcRect.height() / bounds.height(), - bounds.width() / inset, - bounds.height() / inset); - SkASSERT(effect); - return effect; -} -#endif - -/////////////////////////////////////////////////////////////////////////////// - -bool GrMagnifierEffect::onIsEqual(const GrFragmentProcessor& sBase) const { - const GrMagnifierEffect& s = sBase.cast<GrMagnifierEffect>(); - return (this->fBounds == s.fBounds && - this->fSrcRect == s.fSrcRect && - this->fXInvZoom == s.fXInvZoom && - this->fYInvZoom == s.fYInvZoom && - this->fXInvInset == s.fXInvInset && - this->fYInvInset == s.fYInvInset); -} - -#endif - //////////////////////////////////////////////////////////////////////////////// SkMagnifierImageFilter::SkMagnifierImageFilter(const SkRect& srcRect, diff --git a/src/gpu/effects/GrAARectEffect.cpp b/src/gpu/effects/GrAARectEffect.cpp index 0e49e0fad8..48ed6447a1 100644 --- a/src/gpu/effects/GrAARectEffect.cpp +++ b/src/gpu/effects/GrAARectEffect.cpp @@ -13,6 +13,7 @@ #include "glsl/GrGLSLFragmentProcessor.h" #include "glsl/GrGLSLFragmentShaderBuilder.h" #include "glsl/GrGLSLProgramBuilder.h" +#include "GrTexture.h" #include "SkSLCPP.h" #include "SkSLUtil.h" class GrGLSLAARectEffect : public GrGLSLFragmentProcessor { diff --git a/src/gpu/effects/GrArithmeticFP.cpp b/src/gpu/effects/GrArithmeticFP.cpp index 41de6432ef..a9057059b7 100644 --- a/src/gpu/effects/GrArithmeticFP.cpp +++ b/src/gpu/effects/GrArithmeticFP.cpp @@ -13,6 +13,7 @@ #include "glsl/GrGLSLFragmentProcessor.h" #include "glsl/GrGLSLFragmentShaderBuilder.h" #include "glsl/GrGLSLProgramBuilder.h" +#include "GrTexture.h" #include "SkSLCPP.h" #include "SkSLUtil.h" class GrGLSLArithmeticFP : public GrGLSLFragmentProcessor { diff --git a/src/gpu/effects/GrBlurredEdgeFragmentProcessor.cpp b/src/gpu/effects/GrBlurredEdgeFragmentProcessor.cpp index 6dfb6c5216..a531d42116 100644 --- a/src/gpu/effects/GrBlurredEdgeFragmentProcessor.cpp +++ b/src/gpu/effects/GrBlurredEdgeFragmentProcessor.cpp @@ -13,6 +13,7 @@ #include "glsl/GrGLSLFragmentProcessor.h" #include "glsl/GrGLSLFragmentShaderBuilder.h" #include "glsl/GrGLSLProgramBuilder.h" +#include "GrTexture.h" #include "SkSLCPP.h" #include "SkSLUtil.h" class GrGLSLBlurredEdgeFragmentProcessor : public GrGLSLFragmentProcessor { diff --git a/src/gpu/effects/GrCircleEffect.cpp b/src/gpu/effects/GrCircleEffect.cpp index a5adf1cc88..ed3ad518b9 100644 --- a/src/gpu/effects/GrCircleEffect.cpp +++ b/src/gpu/effects/GrCircleEffect.cpp @@ -13,6 +13,7 @@ #include "glsl/GrGLSLFragmentProcessor.h" #include "glsl/GrGLSLFragmentShaderBuilder.h" #include "glsl/GrGLSLProgramBuilder.h" +#include "GrTexture.h" #include "SkSLCPP.h" #include "SkSLUtil.h" class GrGLSLCircleEffect : public GrGLSLFragmentProcessor { diff --git a/src/gpu/effects/GrConfigConversionEffect.cpp b/src/gpu/effects/GrConfigConversionEffect.cpp index 9887cac6b0..b1e4aa758f 100644 --- a/src/gpu/effects/GrConfigConversionEffect.cpp +++ b/src/gpu/effects/GrConfigConversionEffect.cpp @@ -13,6 +13,7 @@ #include "glsl/GrGLSLFragmentProcessor.h" #include "glsl/GrGLSLFragmentShaderBuilder.h" #include "glsl/GrGLSLProgramBuilder.h" +#include "GrTexture.h" #include "SkSLCPP.h" #include "SkSLUtil.h" class GrGLSLConfigConversionEffect : public GrGLSLFragmentProcessor { diff --git a/src/gpu/effects/GrConstColorProcessor.cpp b/src/gpu/effects/GrConstColorProcessor.cpp index b2ac82568b..cfc910ab57 100644 --- a/src/gpu/effects/GrConstColorProcessor.cpp +++ b/src/gpu/effects/GrConstColorProcessor.cpp @@ -13,6 +13,7 @@ #include "glsl/GrGLSLFragmentProcessor.h" #include "glsl/GrGLSLFragmentShaderBuilder.h" #include "glsl/GrGLSLProgramBuilder.h" +#include "GrTexture.h" #include "SkSLCPP.h" #include "SkSLUtil.h" class GrGLSLConstColorProcessor : public GrGLSLFragmentProcessor { diff --git a/src/gpu/effects/GrDitherEffect.cpp b/src/gpu/effects/GrDitherEffect.cpp index d3fdc4fa5d..a66a40d2b7 100644 --- a/src/gpu/effects/GrDitherEffect.cpp +++ b/src/gpu/effects/GrDitherEffect.cpp @@ -13,6 +13,7 @@ #include "glsl/GrGLSLFragmentProcessor.h" #include "glsl/GrGLSLFragmentShaderBuilder.h" #include "glsl/GrGLSLProgramBuilder.h" +#include "GrTexture.h" #include "SkSLCPP.h" #include "SkSLUtil.h" class GrGLSLDitherEffect : public GrGLSLFragmentProcessor { diff --git a/src/gpu/effects/GrEllipseEffect.cpp b/src/gpu/effects/GrEllipseEffect.cpp index 88a07f9bed..7ea975ffde 100644 --- a/src/gpu/effects/GrEllipseEffect.cpp +++ b/src/gpu/effects/GrEllipseEffect.cpp @@ -13,6 +13,7 @@ #include "glsl/GrGLSLFragmentProcessor.h" #include "glsl/GrGLSLFragmentShaderBuilder.h" #include "glsl/GrGLSLProgramBuilder.h" +#include "GrTexture.h" #include "SkSLCPP.h" #include "SkSLUtil.h" class GrGLSLEllipseEffect : public GrGLSLFragmentProcessor { diff --git a/src/gpu/effects/GrLumaColorFilterEffect.cpp b/src/gpu/effects/GrLumaColorFilterEffect.cpp index e09751d9b6..6cd103086f 100644 --- a/src/gpu/effects/GrLumaColorFilterEffect.cpp +++ b/src/gpu/effects/GrLumaColorFilterEffect.cpp @@ -13,6 +13,7 @@ #include "glsl/GrGLSLFragmentProcessor.h" #include "glsl/GrGLSLFragmentShaderBuilder.h" #include "glsl/GrGLSLProgramBuilder.h" +#include "GrTexture.h" #include "SkSLCPP.h" #include "SkSLUtil.h" class GrGLSLLumaColorFilterEffect : public GrGLSLFragmentProcessor { diff --git a/src/gpu/effects/GrMagnifierEffect.cpp b/src/gpu/effects/GrMagnifierEffect.cpp new file mode 100644 index 0000000000..ac00270fef --- /dev/null +++ b/src/gpu/effects/GrMagnifierEffect.cpp @@ -0,0 +1,197 @@ +/* + * Copyright 2017 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +/* + * This file was autogenerated from GrMagnifierEffect.fp; do not modify. + */ +#include "GrMagnifierEffect.h" +#if SK_SUPPORT_GPU +#include "glsl/GrGLSLFragmentProcessor.h" +#include "glsl/GrGLSLFragmentShaderBuilder.h" +#include "glsl/GrGLSLProgramBuilder.h" +#include "GrTexture.h" +#include "SkSLCPP.h" +#include "SkSLUtil.h" +class GrGLSLMagnifierEffect : public GrGLSLFragmentProcessor { +public: + GrGLSLMagnifierEffect() {} + void emitCode(EmitArgs& args) override { + GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder; + const GrMagnifierEffect& _outer = args.fFp.cast<GrMagnifierEffect>(); + (void)_outer; + auto bounds = _outer.bounds(); + (void)bounds; + auto srcRect = _outer.srcRect(); + (void)srcRect; + auto xInvZoom = _outer.xInvZoom(); + (void)xInvZoom; + auto yInvZoom = _outer.yInvZoom(); + (void)yInvZoom; + auto xInvInset = _outer.xInvInset(); + (void)xInvInset; + auto yInvInset = _outer.yInvInset(); + (void)yInvInset; + fBoundsUniformVar = args.fUniformHandler->addUniform( + kFragment_GrShaderFlag, kFloat4_GrSLType, kDefault_GrSLPrecision, "boundsUniform"); + fXInvZoomVar = args.fUniformHandler->addUniform( + kFragment_GrShaderFlag, kFloat_GrSLType, kDefault_GrSLPrecision, "xInvZoom"); + fYInvZoomVar = args.fUniformHandler->addUniform( + kFragment_GrShaderFlag, kFloat_GrSLType, kDefault_GrSLPrecision, "yInvZoom"); + fXInvInsetVar = args.fUniformHandler->addUniform( + kFragment_GrShaderFlag, kFloat_GrSLType, kDefault_GrSLPrecision, "xInvInset"); + fYInvInsetVar = args.fUniformHandler->addUniform( + kFragment_GrShaderFlag, kFloat_GrSLType, kDefault_GrSLPrecision, "yInvInset"); + fOffsetVar = args.fUniformHandler->addUniform( + kFragment_GrShaderFlag, kHalf2_GrSLType, kDefault_GrSLPrecision, "offset"); + SkString sk_TransformedCoords2D_0 = fragBuilder->ensureCoords2D(args.fTransformedCoords[0]); + fragBuilder->codeAppendf( + "float2 coord = %s;\nfloat2 zoom_coord = float2(%s + half2(coord * " + "float2(half2(half(%s), half(%s)))));\nfloat2 delta = (coord - %s.xy) * " + "%s.zw;\ndelta = min(delta, float2(half2(1.0, 1.0) - half2(delta)));\ndelta *= " + "float2(half2(half(%s), half(%s)));\nhalf weight = 0.0;\nif (delta.x < 2.0 && " + "delta.y < 2.0) {\n delta = float2(half2(2.0, 2.0) - half2(delta));\n half " + "dist = half(length(delta));\n dist = half(max(2.0 - float(dist), 0.0));\n " + "weight = half(min(float(dist * dist), 1.0));\n} else {\n ", + sk_TransformedCoords2D_0.c_str(), + args.fUniformHandler->getUniformCStr(fOffsetVar), + args.fUniformHandler->getUniformCStr(fXInvZoomVar), + args.fUniformHandler->getUniformCStr(fYInvZoomVar), + args.fUniformHandler->getUniformCStr(fBoundsUniformVar), + args.fUniformHandler->getUniformCStr(fBoundsUniformVar), + args.fUniformHandler->getUniformCStr(fXInvInsetVar), + args.fUniformHandler->getUniformCStr(fYInvInsetVar)); + fragBuilder->codeAppendf( + "float2 delta_squared = delta * delta;\n weight = half(min(min(delta_squared.x, " + "delta_squared.y), 1.0));\n}\n%s = texture(%s, mix(coord, zoom_coord, " + "float(weight))).%s;\n", + args.fOutputColor, + fragBuilder->getProgramBuilder()->samplerVariable(args.fTexSamplers[0]).c_str(), + fragBuilder->getProgramBuilder()->samplerSwizzle(args.fTexSamplers[0]).c_str()); + } + +private: + void onSetData(const GrGLSLProgramDataManager& pdman, + const GrFragmentProcessor& _proc) override { + const GrMagnifierEffect& _outer = _proc.cast<GrMagnifierEffect>(); + { + pdman.set1f(fXInvZoomVar, _outer.xInvZoom()); + pdman.set1f(fYInvZoomVar, _outer.yInvZoom()); + pdman.set1f(fXInvInsetVar, _outer.xInvInset()); + pdman.set1f(fYInvInsetVar, _outer.yInvInset()); + } + GrSurfaceProxy& srcProxy = *_outer.textureSampler(0).proxy(); + GrTexture& src = *srcProxy.priv().peekTexture(); + (void)src; + auto bounds = _outer.bounds(); + (void)bounds; + UniformHandle& boundsUniform = fBoundsUniformVar; + (void)boundsUniform; + auto srcRect = _outer.srcRect(); + (void)srcRect; + UniformHandle& xInvZoom = fXInvZoomVar; + (void)xInvZoom; + UniformHandle& yInvZoom = fYInvZoomVar; + (void)yInvZoom; + UniformHandle& xInvInset = fXInvInsetVar; + (void)xInvInset; + UniformHandle& yInvInset = fYInvInsetVar; + (void)yInvInset; + UniformHandle& offset = fOffsetVar; + (void)offset; + + SkScalar invW = 1.0f / src.width(); + SkScalar invH = 1.0f / src.height(); + + { + SkScalar y = srcRect.y() * invH; + if (srcProxy.origin() != kTopLeft_GrSurfaceOrigin) { + y = 1.0f - (srcRect.height() / bounds.height()) - y; + } + + pdman.set2f(offset, srcRect.x() * invW, y); + } + + { + SkScalar y = bounds.y() * invH; + if (srcProxy.origin() != kTopLeft_GrSurfaceOrigin) { + y = 1.0f - bounds.height() * invH; + } + + pdman.set4f(boundsUniform, + bounds.x() * invW, + y, + SkIntToScalar(src.width()) / bounds.width(), + SkIntToScalar(src.height()) / bounds.height()); + } + } + UniformHandle fBoundsUniformVar; + UniformHandle fOffsetVar; + UniformHandle fSrcVar; + UniformHandle fXInvZoomVar; + UniformHandle fYInvZoomVar; + UniformHandle fXInvInsetVar; + UniformHandle fYInvInsetVar; +}; +GrGLSLFragmentProcessor* GrMagnifierEffect::onCreateGLSLInstance() const { + return new GrGLSLMagnifierEffect(); +} +void GrMagnifierEffect::onGetGLSLProcessorKey(const GrShaderCaps& caps, + GrProcessorKeyBuilder* b) const {} +bool GrMagnifierEffect::onIsEqual(const GrFragmentProcessor& other) const { + const GrMagnifierEffect& that = other.cast<GrMagnifierEffect>(); + (void)that; + if (fSrc != that.fSrc) return false; + if (fBounds != that.fBounds) return false; + if (fSrcRect != that.fSrcRect) return false; + if (fXInvZoom != that.fXInvZoom) return false; + if (fYInvZoom != that.fYInvZoom) return false; + if (fXInvInset != that.fXInvInset) return false; + if (fYInvInset != that.fYInvInset) return false; + return true; +} +GrMagnifierEffect::GrMagnifierEffect(const GrMagnifierEffect& src) + : INHERITED(kGrMagnifierEffect_ClassID, src.optimizationFlags()) + , fSrc(src.fSrc) + , fBounds(src.fBounds) + , fSrcRect(src.fSrcRect) + , fXInvZoom(src.fXInvZoom) + , fYInvZoom(src.fYInvZoom) + , fXInvInset(src.fXInvInset) + , fYInvInset(src.fYInvInset) + , fSrcCoordTransform(src.fSrcCoordTransform) { + this->addTextureSampler(&fSrc); + this->addCoordTransform(&fSrcCoordTransform); +} +std::unique_ptr<GrFragmentProcessor> GrMagnifierEffect::clone() const { + return std::unique_ptr<GrFragmentProcessor>(new GrMagnifierEffect(*this)); +} +GR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrMagnifierEffect); +#if GR_TEST_UTILS +std::unique_ptr<GrFragmentProcessor> GrMagnifierEffect::TestCreate(GrProcessorTestData* d) { + sk_sp<GrTextureProxy> proxy = d->textureProxy(0); + const int kMaxWidth = 200; + const int kMaxHeight = 200; + const SkScalar kMaxInset = 20.0f; + uint32_t width = d->fRandom->nextULessThan(kMaxWidth); + uint32_t height = d->fRandom->nextULessThan(kMaxHeight); + SkScalar inset = d->fRandom->nextRangeScalar(1.0f, kMaxInset); + + SkIRect bounds = SkIRect::MakeWH(SkIntToScalar(kMaxWidth), SkIntToScalar(kMaxHeight)); + SkRect srcRect = SkRect::MakeWH(SkIntToScalar(width), SkIntToScalar(height)); + + auto effect = GrMagnifierEffect::Make(std::move(proxy), + bounds, + srcRect, + srcRect.width() / bounds.width(), + srcRect.height() / bounds.height(), + bounds.width() / inset, + bounds.height() / inset); + SkASSERT(effect); + return effect; +} +#endif +#endif diff --git a/src/gpu/effects/GrMagnifierEffect.fp b/src/gpu/effects/GrMagnifierEffect.fp new file mode 100644 index 0000000000..962c1a0160 --- /dev/null +++ b/src/gpu/effects/GrMagnifierEffect.fp @@ -0,0 +1,85 @@ +in uniform sampler2D src; +layout(ctype=SkIRect) in int4 bounds; +uniform float4 boundsUniform; +layout(ctype=SkRect) in float4 srcRect; +in uniform float xInvZoom; +in uniform float yInvZoom; +in uniform float xInvInset; +in uniform float yInvInset; + +uniform half2 offset; + +@coordTransform(src) { + SkMatrix::I() +} + +void main() { + float2 coord = sk_TransformedCoords2D[0]; + float2 zoom_coord = offset + coord * half2(xInvZoom, yInvZoom); + float2 delta = (coord - boundsUniform.xy) * boundsUniform.zw; + delta = min(delta, half2(1.0, 1.0) - delta); + delta *= half2(xInvInset, yInvInset); + + half weight = 0.0; + if (delta.s < 2.0 && delta.t < 2.0) { + delta = half2(2.0, 2.0) - delta; + half dist = length(delta); + dist = max(2.0 - dist, 0.0); + weight = min(dist * dist, 1.0); + } else { + float2 delta_squared = delta * delta; + weight = min(min(delta_squared.x, delta_squared.y), 1.0); + } + + sk_OutColor = texture(src, mix(coord, zoom_coord, weight)); +} + +@setData(pdman) { + SkScalar invW = 1.0f / src.width(); + SkScalar invH = 1.0f / src.height(); + + { + SkScalar y = srcRect.y() * invH; + if (srcProxy.origin() != kTopLeft_GrSurfaceOrigin) { + y = 1.0f - (srcRect.height() / bounds.height()) - y; + } + + pdman.set2f(offset, srcRect.x() * invW, y); + } + + { + SkScalar y = bounds.y() * invH; + if (srcProxy.origin() != kTopLeft_GrSurfaceOrigin) { + y = 1.0f - bounds.height() * invH; + } + + pdman.set4f(boundsUniform, + bounds.x() * invW, + y, + SkIntToScalar(src.width()) / bounds.width(), + SkIntToScalar(src.height()) / bounds.height()); + } +} + +@test(d) { + sk_sp<GrTextureProxy> proxy = d->textureProxy(0); + const int kMaxWidth = 200; + const int kMaxHeight = 200; + const SkScalar kMaxInset = 20.0f; + uint32_t width = d->fRandom->nextULessThan(kMaxWidth); + uint32_t height = d->fRandom->nextULessThan(kMaxHeight); + SkScalar inset = d->fRandom->nextRangeScalar(1.0f, kMaxInset); + + SkIRect bounds = SkIRect::MakeWH(SkIntToScalar(kMaxWidth), SkIntToScalar(kMaxHeight)); + SkRect srcRect = SkRect::MakeWH(SkIntToScalar(width), SkIntToScalar(height)); + + auto effect = GrMagnifierEffect::Make(std::move(proxy), + bounds, + srcRect, + srcRect.width() / bounds.width(), + srcRect.height() / bounds.height(), + bounds.width() / inset, + bounds.height() / inset); + SkASSERT(effect); + return effect; +} diff --git a/src/gpu/effects/GrMagnifierEffect.h b/src/gpu/effects/GrMagnifierEffect.h new file mode 100644 index 0000000000..13904f983f --- /dev/null +++ b/src/gpu/effects/GrMagnifierEffect.h @@ -0,0 +1,65 @@ +/* + * Copyright 2017 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +/* + * This file was autogenerated from GrMagnifierEffect.fp; do not modify. + */ +#ifndef GrMagnifierEffect_DEFINED +#define GrMagnifierEffect_DEFINED +#include "SkTypes.h" +#if SK_SUPPORT_GPU +#include "GrFragmentProcessor.h" +#include "GrCoordTransform.h" +class GrMagnifierEffect : public GrFragmentProcessor { +public: + SkIRect bounds() const { return fBounds; } + SkRect srcRect() const { return fSrcRect; } + float xInvZoom() const { return fXInvZoom; } + float yInvZoom() const { return fYInvZoom; } + float xInvInset() const { return fXInvInset; } + float yInvInset() const { return fYInvInset; } + static std::unique_ptr<GrFragmentProcessor> Make(sk_sp<GrTextureProxy> src, SkIRect bounds, + SkRect srcRect, float xInvZoom, float yInvZoom, + float xInvInset, float yInvInset) { + return std::unique_ptr<GrFragmentProcessor>(new GrMagnifierEffect( + src, bounds, srcRect, xInvZoom, yInvZoom, xInvInset, yInvInset)); + } + GrMagnifierEffect(const GrMagnifierEffect& src); + std::unique_ptr<GrFragmentProcessor> clone() const override; + const char* name() const override { return "MagnifierEffect"; } + +private: + GrMagnifierEffect(sk_sp<GrTextureProxy> src, SkIRect bounds, SkRect srcRect, float xInvZoom, + float yInvZoom, float xInvInset, float yInvInset) + : INHERITED(kGrMagnifierEffect_ClassID, kNone_OptimizationFlags) + , fSrc(std::move(src)) + , fBounds(bounds) + , fSrcRect(srcRect) + , fXInvZoom(xInvZoom) + , fYInvZoom(yInvZoom) + , fXInvInset(xInvInset) + , fYInvInset(yInvInset) + , fSrcCoordTransform(SkMatrix::I(), fSrc.proxy()) { + this->addTextureSampler(&fSrc); + this->addCoordTransform(&fSrcCoordTransform); + } + GrGLSLFragmentProcessor* onCreateGLSLInstance() const override; + void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override; + bool onIsEqual(const GrFragmentProcessor&) const override; + GR_DECLARE_FRAGMENT_PROCESSOR_TEST + TextureSampler fSrc; + SkIRect fBounds; + SkRect fSrcRect; + float fXInvZoom; + float fYInvZoom; + float fXInvInset; + float fYInvInset; + GrCoordTransform fSrcCoordTransform; + typedef GrFragmentProcessor INHERITED; +}; +#endif +#endif diff --git a/src/gpu/effects/GrOverdrawFragmentProcessor.cpp b/src/gpu/effects/GrOverdrawFragmentProcessor.cpp index 31ab53d397..9d9e4fecc3 100644 --- a/src/gpu/effects/GrOverdrawFragmentProcessor.cpp +++ b/src/gpu/effects/GrOverdrawFragmentProcessor.cpp @@ -13,6 +13,7 @@ #include "glsl/GrGLSLFragmentProcessor.h" #include "glsl/GrGLSLFragmentShaderBuilder.h" #include "glsl/GrGLSLProgramBuilder.h" +#include "GrTexture.h" #include "SkSLCPP.h" #include "SkSLUtil.h" class GrGLSLOverdrawFragmentProcessor : public GrGLSLFragmentProcessor { diff --git a/src/gpu/effects/GrPremulInputFragmentProcessor.cpp b/src/gpu/effects/GrPremulInputFragmentProcessor.cpp index a90f52944e..2e3beceec3 100644 --- a/src/gpu/effects/GrPremulInputFragmentProcessor.cpp +++ b/src/gpu/effects/GrPremulInputFragmentProcessor.cpp @@ -13,6 +13,7 @@ #include "glsl/GrGLSLFragmentProcessor.h" #include "glsl/GrGLSLFragmentShaderBuilder.h" #include "glsl/GrGLSLProgramBuilder.h" +#include "GrTexture.h" #include "SkSLCPP.h" #include "SkSLUtil.h" class GrGLSLPremulInputFragmentProcessor : public GrGLSLFragmentProcessor { diff --git a/src/gpu/effects/GrRectBlurEffect.cpp b/src/gpu/effects/GrRectBlurEffect.cpp index 573c1313a0..e656d848de 100644 --- a/src/gpu/effects/GrRectBlurEffect.cpp +++ b/src/gpu/effects/GrRectBlurEffect.cpp @@ -13,6 +13,7 @@ #include "glsl/GrGLSLFragmentProcessor.h" #include "glsl/GrGLSLFragmentShaderBuilder.h" #include "glsl/GrGLSLProgramBuilder.h" +#include "GrTexture.h" #include "SkSLCPP.h" #include "SkSLUtil.h" class GrGLSLRectBlurEffect : public GrGLSLFragmentProcessor { @@ -113,7 +114,8 @@ private: (void)rect; auto sigma = _outer.sigma(); (void)sigma; - UniformHandle& blurProfile = fBlurProfileVar; + GrSurfaceProxy& blurProfileProxy = *_outer.textureSampler(0).proxy(); + GrTexture& blurProfile = *blurProfileProxy.priv().peekTexture(); (void)blurProfile; UniformHandle& proxyRectHalf = fProxyRectHalfVar; (void)proxyRectHalf; diff --git a/src/gpu/effects/GrSimpleTextureEffect.cpp b/src/gpu/effects/GrSimpleTextureEffect.cpp index 387731e956..d1efc8520e 100644 --- a/src/gpu/effects/GrSimpleTextureEffect.cpp +++ b/src/gpu/effects/GrSimpleTextureEffect.cpp @@ -13,6 +13,7 @@ #include "glsl/GrGLSLFragmentProcessor.h" #include "glsl/GrGLSLFragmentShaderBuilder.h" #include "glsl/GrGLSLProgramBuilder.h" +#include "GrTexture.h" #include "SkSLCPP.h" #include "SkSLUtil.h" class GrGLSLSimpleTextureEffect : public GrGLSLFragmentProcessor { diff --git a/src/gpu/effects/GrUnpremulInputFragmentProcessor.cpp b/src/gpu/effects/GrUnpremulInputFragmentProcessor.cpp index 273643f78d..6e33763f9d 100644 --- a/src/gpu/effects/GrUnpremulInputFragmentProcessor.cpp +++ b/src/gpu/effects/GrUnpremulInputFragmentProcessor.cpp @@ -13,6 +13,7 @@ #include "glsl/GrGLSLFragmentProcessor.h" #include "glsl/GrGLSLFragmentShaderBuilder.h" #include "glsl/GrGLSLProgramBuilder.h" +#include "GrTexture.h" #include "SkSLCPP.h" #include "SkSLUtil.h" class GrGLSLUnpremulInputFragmentProcessor : public GrGLSLFragmentProcessor { diff --git a/src/sksl/SkSLCPPCodeGenerator.cpp b/src/sksl/SkSLCPPCodeGenerator.cpp index 5b0b497fa1..c5ddc7a76e 100644 --- a/src/sksl/SkSLCPPCodeGenerator.cpp +++ b/src/sksl/SkSLCPPCodeGenerator.cpp @@ -176,6 +176,12 @@ void CPPCodeGenerator::writeRuntimeValue(const Type& type, const Layout& layout, } else if (type.kind() == Type::kEnum_Kind) { this->write("%d"); fFormatArgs.push_back("(int) " + cppCode); + } else if (type == *fContext.fInt4_Type || type == *fContext.fShort4_Type) { + this->write(type.name() + "(%d, %d, %d, %d)"); + fFormatArgs.push_back(cppCode + ".left()"); + fFormatArgs.push_back(cppCode + ".top()"); + fFormatArgs.push_back(cppCode + ".right()"); + fFormatArgs.push_back(cppCode + ".bottom()"); } else { printf("unsupported runtime value type '%s'\n", String(type.fName).c_str()); ASSERT(false); @@ -589,6 +595,7 @@ void CPPCodeGenerator::writeSetData(std::vector<const Variable*>& uniforms) { this->writef(" }\n"); } if (section) { + int samplerIndex = 0; for (const auto& p : fProgram.fElements) { if (ProgramElement::kVar_Kind == p->fKind) { const VarDeclarations* decls = (const VarDeclarations*) p.get(); @@ -596,7 +603,15 @@ void CPPCodeGenerator::writeSetData(std::vector<const Variable*>& uniforms) { VarDeclaration& decl = (VarDeclaration&) *raw; String nameString(decl.fVar->fName); const char* name = nameString.c_str(); - if (needs_uniform_var(*decl.fVar)) { + if (decl.fVar->fType.kind() == Type::kSampler_Kind) { + this->writef(" GrSurfaceProxy& %sProxy = " + "*_outer.textureSampler(%d).proxy();\n", + name, samplerIndex); + this->writef(" GrTexture& %s = *%sProxy.priv().peekTexture();\n", + name, name); + this->writef(" (void) %s;\n", name); + ++samplerIndex; + } else if (needs_uniform_var(*decl.fVar)) { this->writef(" UniformHandle& %s = %sVar;\n" " (void) %s;\n", name, HCodeGenerator::FieldName(name).c_str(), name); @@ -755,6 +770,7 @@ bool CPPCodeGenerator::generateCode() { this->writef("#include \"glsl/GrGLSLFragmentProcessor.h\"\n" "#include \"glsl/GrGLSLFragmentShaderBuilder.h\"\n" "#include \"glsl/GrGLSLProgramBuilder.h\"\n" + "#include \"GrTexture.h\"\n" "#include \"SkSLCPP.h\"\n" "#include \"SkSLUtil.h\"\n" "class GrGLSL%s : public GrGLSLFragmentProcessor {\n" diff --git a/tests/SkSLFPTest.cpp b/tests/SkSLFPTest.cpp index 0358f07d59..982591082b 100644 --- a/tests/SkSLFPTest.cpp +++ b/tests/SkSLFPTest.cpp @@ -120,6 +120,7 @@ DEF_TEST(SkSLFPHelloWorld, r) { "#include \"glsl/GrGLSLFragmentProcessor.h\"\n" "#include \"glsl/GrGLSLFragmentShaderBuilder.h\"\n" "#include \"glsl/GrGLSLProgramBuilder.h\"\n" + "#include \"GrTexture.h\"\n" "#include \"SkSLCPP.h\"\n" "#include \"SkSLUtil.h\"\n" "class GrGLSLTest : public GrGLSLFragmentProcessor {\n" |