diff options
author | Ethan Nicholas <ethannicholas@google.com> | 2018-07-19 20:10:37 +0000 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2018-07-19 20:10:46 +0000 |
commit | 6c48e4d11ce80fa5cfef56e13b2d5847fe94a7cc (patch) | |
tree | 57e5d832d16aa9a0447e5102fe9811e39f8403d9 /src/gpu | |
parent | 736db1081b378ac8c167dfbc0322470d28c1cb3e (diff) |
Reland "Revert "added GrSkSLFP and converted DitherEffect to use it""
This reverts commit 97ae0c89025dfd791047f5701e57d58da37c125c.
Reason for revert: Breaking ANGLE.
Original change's description:
> Revert "Revert "added GrSkSLFP and converted DitherEffect to use it""
>
> This reverts commit f2030783094e502fb74221077a5ee7cb41287fe4.
>
> Bug: skia:
> Change-Id: Icaaa8b3ea652a8f126bfbcc788a360493a7ebe3e
> Reviewed-on: https://skia-review.googlesource.com/137391
> Commit-Queue: Ethan Nicholas <ethannicholas@google.com>
> Reviewed-by: Brian Salomon <bsalomon@google.com>
TBR=bsalomon@google.com,robertphillips@google.com,ethannicholas@google.com
Change-Id: I65d6d2707fceab0a99121c528d1b848d23e34bfa
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Bug: skia:
Reviewed-on: https://skia-review.googlesource.com/142588
Reviewed-by: Ethan Nicholas <ethannicholas@google.com>
Commit-Queue: Ethan Nicholas <ethannicholas@google.com>
Diffstat (limited to 'src/gpu')
-rw-r--r-- | src/gpu/GrContext.cpp | 9 | ||||
-rw-r--r-- | src/gpu/GrContextPriv.h | 5 | ||||
-rw-r--r-- | src/gpu/GrContextThreadSafeProxyPriv.h | 1 | ||||
-rw-r--r-- | src/gpu/GrDDLContext.cpp | 2 | ||||
-rw-r--r-- | src/gpu/GrDirectContext.cpp | 6 | ||||
-rw-r--r-- | src/gpu/GrProcessor.h | 1 | ||||
-rw-r--r-- | src/gpu/SkGr.cpp | 86 | ||||
-rw-r--r-- | src/gpu/SkGr.h | 2 | ||||
-rw-r--r-- | src/gpu/effects/GrDitherEffect.cpp | 75 | ||||
-rw-r--r-- | src/gpu/effects/GrDitherEffect.fp | 85 | ||||
-rw-r--r-- | src/gpu/effects/GrDitherEffect.h | 67 | ||||
-rw-r--r-- | src/gpu/effects/GrRectBlurEffect.cpp | 34 | ||||
-rw-r--r-- | src/gpu/effects/GrSkSLFP.cpp | 268 | ||||
-rw-r--r-- | src/gpu/effects/GrSkSLFP.h | 147 | ||||
-rw-r--r-- | src/gpu/glsl/GrGLSLShaderBuilder.h | 2 |
15 files changed, 253 insertions, 537 deletions
diff --git a/src/gpu/GrContext.cpp b/src/gpu/GrContext.cpp index 8380f0d711..caed7298ae 100644 --- a/src/gpu/GrContext.cpp +++ b/src/gpu/GrContext.cpp @@ -37,9 +37,7 @@ #include "SkTaskGroup.h" #include "SkUnPreMultiplyPriv.h" #include "effects/GrConfigConversionEffect.h" -#include "effects/GrSkSLFP.h" #include "text/GrTextBlobCache.h" -#include <unordered_map> #define ASSERT_OWNED_PROXY(P) \ SkASSERT(!(P) || !((P)->priv().peekTexture()) || (P)->priv().peekTexture()->getContext() == this) @@ -162,6 +160,7 @@ GrContext::~GrContext() { if (fDrawingManager) { fDrawingManager->cleanup(); } + fTextureStripAtlasManager = nullptr; delete fResourceProvider; delete fResourceCache; @@ -173,13 +172,11 @@ GrContext::~GrContext() { GrContextThreadSafeProxy::GrContextThreadSafeProxy(sk_sp<const GrCaps> caps, uint32_t uniqueID, GrBackend backend, - const GrContextOptions& options, - sk_sp<GrSkSLFPFactoryCache> cache) + const GrContextOptions& options) : fCaps(std::move(caps)) , fContextUniqueID(uniqueID) , fBackend(backend) - , fOptions(options) - , fFPFactoryCache(std::move(cache)) {} + , fOptions(options) {} GrContextThreadSafeProxy::~GrContextThreadSafeProxy() = default; diff --git a/src/gpu/GrContextPriv.h b/src/gpu/GrContextPriv.h index 1b90dafa37..4f392f88b3 100644 --- a/src/gpu/GrContextPriv.h +++ b/src/gpu/GrContextPriv.h @@ -16,7 +16,6 @@ class GrBackendRenderTarget; class GrOpMemoryPool; class GrOnFlushCallbackObject; class GrSemaphore; -class GrSkSLFPFactory; class GrSurfaceProxy; class GrTextureContext; @@ -280,10 +279,6 @@ public: GrContextOptions::PersistentCache* getPersistentCache() { return fContext->fPersistentCache; } - sk_sp<GrSkSLFPFactoryCache> getFPFactoryCache() { - return fContext->fFPFactoryCache; - } - /** This is only useful for debug purposes */ SkDEBUGCODE(GrSingleOwner* debugSingleOwner() const { return &fContext->fSingleOwner; } ) diff --git a/src/gpu/GrContextThreadSafeProxyPriv.h b/src/gpu/GrContextThreadSafeProxyPriv.h index b3a4eab021..8e299c8180 100644 --- a/src/gpu/GrContextThreadSafeProxyPriv.h +++ b/src/gpu/GrContextThreadSafeProxyPriv.h @@ -23,7 +23,6 @@ public: sk_sp<const GrCaps> refCaps() const { return fProxy->fCaps; } uint32_t contextUniqueID() const { return fProxy->fContextUniqueID; } GrBackend backend() const { return fProxy->fBackend; } - sk_sp<GrSkSLFPFactoryCache> fpFactoryCache() const { return fProxy->fFPFactoryCache; } private: explicit GrContextThreadSafeProxyPriv(GrContextThreadSafeProxy* proxy) : fProxy(proxy) {} diff --git a/src/gpu/GrDDLContext.cpp b/src/gpu/GrDDLContext.cpp index eb5ed29e6b..1ae640c3e3 100644 --- a/src/gpu/GrDDLContext.cpp +++ b/src/gpu/GrDDLContext.cpp @@ -19,8 +19,6 @@ public: GrDDLContext(sk_sp<GrContextThreadSafeProxy> proxy) : INHERITED(proxy->priv().backend(), proxy->priv().contextUniqueID()) { fCaps = proxy->priv().refCaps(); - fFPFactoryCache = proxy->priv().fpFactoryCache(); - SkASSERT(fFPFactoryCache); fThreadSafeProxy = std::move(proxy); } diff --git a/src/gpu/GrDirectContext.cpp b/src/gpu/GrDirectContext.cpp index c87078b98b..3e4b8ef5fa 100644 --- a/src/gpu/GrDirectContext.cpp +++ b/src/gpu/GrDirectContext.cpp @@ -10,7 +10,6 @@ #include "GrContextPriv.h" #include "GrGpu.h" -#include "effects/GrSkSLFP.h" #include "gl/GrGLGpu.h" #include "mock/GrMockGpu.h" #include "text/GrGlyphCache.h" @@ -59,10 +58,9 @@ protected: bool init(const GrContextOptions& options) override { SkASSERT(fCaps); // should've been set in ctor SkASSERT(!fThreadSafeProxy); - SkASSERT(!fFPFactoryCache); - fFPFactoryCache.reset(new GrSkSLFPFactoryCache()); + fThreadSafeProxy.reset(new GrContextThreadSafeProxy(fCaps, this->uniqueID(), - fBackend, options, fFPFactoryCache)); + fBackend, options)); if (!INHERITED::initCommon(options)) { return false; diff --git a/src/gpu/GrProcessor.h b/src/gpu/GrProcessor.h index 34f51935af..038ce16717 100644 --- a/src/gpu/GrProcessor.h +++ b/src/gpu/GrProcessor.h @@ -131,7 +131,6 @@ public: kGrRRectBlurEffect_ClassID, kGrRRectShadowGeoProc_ClassID, kGrSimpleTextureEffect_ClassID, - kGrSkSLFP_ClassID, kGrSpecularLightingEffect_ClassID, kGrSRGBEffect_ClassID, kGrSweepGradient_ClassID, diff --git a/src/gpu/SkGr.cpp b/src/gpu/SkGr.cpp index 9082fc4222..5baf0d4017 100644 --- a/src/gpu/SkGr.cpp +++ b/src/gpu/SkGr.cpp @@ -37,49 +37,9 @@ #include "SkTraceEvent.h" #include "effects/GrBicubicEffect.h" #include "effects/GrConstColorProcessor.h" +#include "effects/GrDitherEffect.h" #include "effects/GrPorterDuffXferProcessor.h" #include "effects/GrXfermodeFragmentProcessor.h" -#include "effects/GrSkSLFP.h" - -const char* SKSL_DITHER_SRC = R"( -// This controls the range of values added to color channels -layout(key) in int rangeType; - -void main(int x, int y, inout half4 color) { - half value; - half range; - @switch (rangeType) { - case 0: - range = 1.0 / 255.0; - break; - case 1: - range = 1.0 / 63.0; - break; - default: - // Experimentally this looks better than the expected value of 1/15. - range = 1.0 / 15.0; - break; - } - @if (sk_Caps.integerSupport) { - // This ordered-dither code is lifted from the cpu backend. - uint x = uint(x); - uint y = uint(y); - uint m = (y & 1) << 5 | (x & 1) << 4 | - (y & 2) << 2 | (x & 2) << 1 | - (y & 4) >> 1 | (x & 4) >> 2; - value = half(m) * 1.0 / 64.0 - 63.0 / 128.0; - } else { - // Simulate the integer effect used above using step/mod. For speed, simulates a 4x4 - // dither pattern rather than an 8x8 one. - half4 modValues = mod(float4(x, y, x, y), half4(2.0, 2.0, 4.0, 4.0)); - half4 stepValues = step(modValues, half4(1.0, 1.0, 2.0, 2.0)); - value = dot(stepValues, half4(8.0 / 16.0, 4.0 / 16.0, 2.0 / 16.0, 1.0 / 16.0)) - 15.0 / 32.0; - } - // For each color channel, add the random offset to the channel value and then clamp - // between 0 and alpha to keep the color premultiplied. - color = half4(clamp(color.rgb + value * range, 0.0, color.a), color.a); -} -)"; GrSurfaceDesc GrImageInfoToSurfaceDesc(const SkImageInfo& info) { GrSurfaceDesc desc; @@ -324,39 +284,6 @@ static inline bool blend_requires_shader(const SkBlendMode mode) { return SkBlendMode::kDst != mode; } -#ifndef SK_IGNORE_GPU_DITHER -static inline int32_t dither_range_type_for_config(GrPixelConfig dstConfig) { - switch (dstConfig) { - case kGray_8_GrPixelConfig: - case kGray_8_as_Lum_GrPixelConfig: - case kGray_8_as_Red_GrPixelConfig: - case kRGBA_8888_GrPixelConfig: - case kRGB_888_GrPixelConfig: - case kBGRA_8888_GrPixelConfig: - return 0; - case kRGB_565_GrPixelConfig: - return 1; - case kRGBA_4444_GrPixelConfig: - return 2; - case kUnknown_GrPixelConfig: - case kSRGBA_8888_GrPixelConfig: - case kSBGRA_8888_GrPixelConfig: - case kRGBA_1010102_GrPixelConfig: - case kAlpha_half_GrPixelConfig: - case kAlpha_half_as_Red_GrPixelConfig: - case kRGBA_float_GrPixelConfig: - case kRG_float_GrPixelConfig: - case kRGBA_half_GrPixelConfig: - case kAlpha_8_GrPixelConfig: - case kAlpha_8_as_Alpha_GrPixelConfig: - case kAlpha_8_as_Red_GrPixelConfig: - return -1; - } - SkASSERT(false); - return 0; -} -#endif - static inline bool skpaint_to_grpaint_impl(GrContext* context, const GrColorSpaceInfo& colorSpaceInfo, const SkPaint& skPaint, @@ -484,14 +411,9 @@ static inline bool skpaint_to_grpaint_impl(GrContext* context, SkColorType ct = SkColorType::kRGB_565_SkColorType; GrPixelConfigToColorType(colorSpaceInfo.config(), &ct); if (SkPaintPriv::ShouldDither(skPaint, ct) && grPaint->numColorFragmentProcessors() > 0) { - int32_t ditherRange = dither_range_type_for_config(colorSpaceInfo.config()); - if (ditherRange >= 0) { - static int ditherIndex = GrSkSLFP::NewIndex(); - auto ditherFP = GrSkSLFP::Make(context, ditherIndex, "Dither", SKSL_DITHER_SRC, - &ditherRange, sizeof(ditherRange)); - if (ditherFP) { - grPaint->addColorFragmentProcessor(std::move(ditherFP)); - } + auto ditherFP = GrDitherEffect::Make(colorSpaceInfo.config()); + if (ditherFP) { + grPaint->addColorFragmentProcessor(std::move(ditherFP)); } } #endif diff --git a/src/gpu/SkGr.h b/src/gpu/SkGr.h index 394b2f2156..ec9f30a3bf 100644 --- a/src/gpu/SkGr.h +++ b/src/gpu/SkGr.h @@ -38,8 +38,6 @@ class SkPixelRef; class SkPixmap; struct SkIRect; -extern const char* SKSL_DITHER_SRC; - //////////////////////////////////////////////////////////////////////////////// // Color type conversions diff --git a/src/gpu/effects/GrDitherEffect.cpp b/src/gpu/effects/GrDitherEffect.cpp new file mode 100644 index 0000000000..17c8776524 --- /dev/null +++ b/src/gpu/effects/GrDitherEffect.cpp @@ -0,0 +1,75 @@ +/* + * Copyright 2018 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 GrDitherEffect.fp; do not modify. + **************************************************************************************************/ +#include "GrDitherEffect.h" +#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 { +public: + GrGLSLDitherEffect() {} + void emitCode(EmitArgs& args) override { + GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder; + const GrDitherEffect& _outer = args.fFp.cast<GrDitherEffect>(); + (void)_outer; + auto rangeType = _outer.rangeType(); + (void)rangeType; + fragBuilder->codeAppendf( + "half value;\nhalf range;\n@switch (%d) {\n case 0:\n range = " + "0.0039215686274509803;\n break;\n case 1:\n range = " + "0.015873015873015872;\n break;\n default:\n range = " + "0.066666666666666666;\n break;\n}\n@if (sk_Caps.integerSupport) {\n " + "uint x = uint(sk_FragCoord.x);\n uint y = uint(sk_FragCoord.y);\n uint m = " + "(((((y & 1) << 5 | (x & 1) << 4) | (y & 2) << 2) | (x & 2) << 1) | (y & 4) >> 1) " + "| (x & 4) >> 2;\n value = float(float(half(m)) / 64.0) - 0.4", + _outer.rangeType()); + fragBuilder->codeAppendf( + "921875;\n} else {\n half4 modValues = half4(mod(sk_FragCoord.xyxy, " + "float4(half4(2.0, 2.0, 4.0, 4.0))));\n half4 stepValues = " + "half4(step(float4(modValues), float4(half4(1.0, 1.0, 2.0, 2.0))));\n value = " + "float(dot(stepValues, half4(0.5, 0.25, 0.125, 0.0625))) - 0.46875;\n}\n%s = " + "half4(clamp(float3(%s.xyz + value * range), 0.0, float(%s.w)), %s.w);\n", + args.fOutputColor, args.fInputColor ? args.fInputColor : "half4(1)", + args.fInputColor ? args.fInputColor : "half4(1)", + args.fInputColor ? args.fInputColor : "half4(1)"); + } + +private: + void onSetData(const GrGLSLProgramDataManager& pdman, + const GrFragmentProcessor& _proc) override {} +}; +GrGLSLFragmentProcessor* GrDitherEffect::onCreateGLSLInstance() const { + return new GrGLSLDitherEffect(); +} +void GrDitherEffect::onGetGLSLProcessorKey(const GrShaderCaps& caps, + GrProcessorKeyBuilder* b) const { + b->add32((int32_t)fRangeType); +} +bool GrDitherEffect::onIsEqual(const GrFragmentProcessor& other) const { + const GrDitherEffect& that = other.cast<GrDitherEffect>(); + (void)that; + if (fRangeType != that.fRangeType) return false; + return true; +} +GrDitherEffect::GrDitherEffect(const GrDitherEffect& src) + : INHERITED(kGrDitherEffect_ClassID, src.optimizationFlags()), fRangeType(src.fRangeType) {} +std::unique_ptr<GrFragmentProcessor> GrDitherEffect::clone() const { + return std::unique_ptr<GrFragmentProcessor>(new GrDitherEffect(*this)); +} +GR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrDitherEffect); +#if GR_TEST_UTILS +std::unique_ptr<GrFragmentProcessor> GrDitherEffect::TestCreate(GrProcessorTestData* testData) { + float range = testData->fRandom->nextRangeF(0.001f, 0.05f); + return std::unique_ptr<GrFragmentProcessor>(new GrDitherEffect(range)); +} +#endif diff --git a/src/gpu/effects/GrDitherEffect.fp b/src/gpu/effects/GrDitherEffect.fp new file mode 100644 index 0000000000..ed6c0e6b70 --- /dev/null +++ b/src/gpu/effects/GrDitherEffect.fp @@ -0,0 +1,85 @@ +/* + * Copyright 2018 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +// This controls the range of values added to color channels +layout(key) in int rangeType; + +@make { + static std::unique_ptr<GrFragmentProcessor> Make(GrPixelConfig dstConfig) { + int rangeType; + switch (dstConfig) { + case kGray_8_GrPixelConfig: + case kGray_8_as_Lum_GrPixelConfig: + case kGray_8_as_Red_GrPixelConfig: + case kRGBA_8888_GrPixelConfig: + case kRGB_888_GrPixelConfig: + case kBGRA_8888_GrPixelConfig: + rangeType = 0; + break; + case kRGB_565_GrPixelConfig: + rangeType = 1; + break; + case kRGBA_4444_GrPixelConfig: + rangeType = 2; + break; + case kUnknown_GrPixelConfig: + case kSRGBA_8888_GrPixelConfig: + case kSBGRA_8888_GrPixelConfig: + case kRGBA_1010102_GrPixelConfig: + case kAlpha_half_GrPixelConfig: + case kAlpha_half_as_Red_GrPixelConfig: + case kRGBA_float_GrPixelConfig: + case kRG_float_GrPixelConfig: + case kRGBA_half_GrPixelConfig: + case kAlpha_8_GrPixelConfig: + case kAlpha_8_as_Alpha_GrPixelConfig: + case kAlpha_8_as_Red_GrPixelConfig: + return nullptr; + } + return std::unique_ptr<GrFragmentProcessor>(new GrDitherEffect(rangeType)); + } +} + +void main() { + half value; + half range; + @switch (rangeType) { + case 0: + range = 1.0 / 255.0; + break; + case 1: + range = 1.0 / 63.0; + break; + default: + // Experimentally this looks better than the expected value of 1/15. + range = 1.0 / 15.0; + break; + } + @if (sk_Caps.integerSupport) { + // This ordered-dither code is lifted from the cpu backend. + uint x = uint(sk_FragCoord.x); + uint y = uint(sk_FragCoord.y); + uint m = (y & 1) << 5 | (x & 1) << 4 | + (y & 2) << 2 | (x & 2) << 1 | + (y & 4) >> 1 | (x & 4) >> 2; + value = half(m) * 1.0 / 64.0 - 63.0 / 128.0; + } else { + // Simulate the integer effect used above using step/mod. For speed, simulates a 4x4 + // dither pattern rather than an 8x8 one. + half4 modValues = mod(sk_FragCoord.xyxy, half4(2.0, 2.0, 4.0, 4.0)); + half4 stepValues = step(modValues, half4(1.0, 1.0, 2.0, 2.0)); + value = dot(stepValues, half4(8.0 / 16.0, 4.0 / 16.0, 2.0 / 16.0, 1.0 / 16.0)) - 15.0 / 32.0; + } + // For each color channel, add the random offset to the channel value and then clamp + // between 0 and alpha to keep the color premultiplied. + sk_OutColor = half4(clamp(sk_InColor.rgb + value * range, 0, sk_InColor.a), sk_InColor.a); +} + +@test(testData) { + float range = testData->fRandom->nextRangeF(0.001f, 0.05f); + return std::unique_ptr<GrFragmentProcessor>(new GrDitherEffect(range)); +} diff --git a/src/gpu/effects/GrDitherEffect.h b/src/gpu/effects/GrDitherEffect.h new file mode 100644 index 0000000000..70adc45e6a --- /dev/null +++ b/src/gpu/effects/GrDitherEffect.h @@ -0,0 +1,67 @@ +/* + * Copyright 2018 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 GrDitherEffect.fp; do not modify. + **************************************************************************************************/ +#ifndef GrDitherEffect_DEFINED +#define GrDitherEffect_DEFINED +#include "SkTypes.h" +#include "GrFragmentProcessor.h" +#include "GrCoordTransform.h" +class GrDitherEffect : public GrFragmentProcessor { +public: + int rangeType() const { return fRangeType; } + + static std::unique_ptr<GrFragmentProcessor> Make(GrPixelConfig dstConfig) { + int rangeType; + switch (dstConfig) { + case kGray_8_GrPixelConfig: + case kGray_8_as_Lum_GrPixelConfig: + case kGray_8_as_Red_GrPixelConfig: + case kRGBA_8888_GrPixelConfig: + case kRGB_888_GrPixelConfig: + case kBGRA_8888_GrPixelConfig: + rangeType = 0; + break; + case kRGB_565_GrPixelConfig: + rangeType = 1; + break; + case kRGBA_4444_GrPixelConfig: + rangeType = 2; + break; + case kUnknown_GrPixelConfig: + case kSRGBA_8888_GrPixelConfig: + case kSBGRA_8888_GrPixelConfig: + case kRGBA_1010102_GrPixelConfig: + case kAlpha_half_GrPixelConfig: + case kAlpha_half_as_Red_GrPixelConfig: + case kRGBA_float_GrPixelConfig: + case kRG_float_GrPixelConfig: + case kRGBA_half_GrPixelConfig: + case kAlpha_8_GrPixelConfig: + case kAlpha_8_as_Alpha_GrPixelConfig: + case kAlpha_8_as_Red_GrPixelConfig: + return nullptr; + } + return std::unique_ptr<GrFragmentProcessor>(new GrDitherEffect(rangeType)); + } + GrDitherEffect(const GrDitherEffect& src); + std::unique_ptr<GrFragmentProcessor> clone() const override; + const char* name() const override { return "DitherEffect"; } + +private: + GrDitherEffect(int rangeType) + : INHERITED(kGrDitherEffect_ClassID, kNone_OptimizationFlags), fRangeType(rangeType) {} + GrGLSLFragmentProcessor* onCreateGLSLInstance() const override; + void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override; + bool onIsEqual(const GrFragmentProcessor&) const override; + GR_DECLARE_FRAGMENT_PROCESSOR_TEST + int fRangeType; + typedef GrFragmentProcessor INHERITED; +}; +#endif diff --git a/src/gpu/effects/GrRectBlurEffect.cpp b/src/gpu/effects/GrRectBlurEffect.cpp index d423b786ce..219fefa713 100644 --- a/src/gpu/effects/GrRectBlurEffect.cpp +++ b/src/gpu/effects/GrRectBlurEffect.cpp @@ -46,13 +46,13 @@ public: fProfileSizeVar = args.fUniformHandler->addUniform(kFragment_GrShaderFlag, kHalf_GrSLType, kDefault_GrSLPrecision, "profileSize"); fragBuilder->codeAppendf( - "/* key */ bool highPrecision = %s;\n@if (highPrecision) {\n float2 " - "translatedPos = sk_FragCoord.xy - %s.xy;\n float width = %s.z - %s.x;\n " - "float height = %s.w - %s.y;\n float2 smallDims = float2(width - float(%s), " - "height - float(%s));\n float center = 2.0 * floor(float(float(%s / 2.0) + " - "0.25)) - 1.0;\n float2 wh = smallDims - float2(center, center);\n half " - "hcoord = half((abs(translatedPos.x - 0.5 * width) - 0.5 * wh.x) / float(%s));\n " - " half hlookup = texture(%s, float2(float(hcoord), ", + "bool highPrecision = %s;\n@if (highPrecision) {\n float2 translatedPos = " + "sk_FragCoord.xy - %s.xy;\n float width = %s.z - %s.x;\n float height = %s.w " + "- %s.y;\n float2 smallDims = float2(width - float(%s), height - float(%s));\n " + " float center = 2.0 * floor(float(float(%s / 2.0) + 0.25)) - 1.0;\n float2 wh " + "= smallDims - float2(center, center);\n half hcoord = " + "half((abs(translatedPos.x - 0.5 * width) - 0.5 * wh.x) / float(%s));\n half " + "hlookup = texture(%s, float2(float(hcoord), 0.5)).%s.w", (highPrecision ? "true" : "false"), args.fUniformHandler->getUniformCStr(fRectVar), args.fUniformHandler->getUniformCStr(fRectVar), args.fUniformHandler->getUniformCStr(fRectVar), @@ -62,16 +62,16 @@ public: args.fUniformHandler->getUniformCStr(fProfileSizeVar), args.fUniformHandler->getUniformCStr(fProfileSizeVar), args.fUniformHandler->getUniformCStr(fProfileSizeVar), - fragBuilder->getProgramBuilder()->samplerVariable(args.fTexSamplers[0]).c_str()); + fragBuilder->getProgramBuilder()->samplerVariable(args.fTexSamplers[0]).c_str(), + fragBuilder->getProgramBuilder()->samplerSwizzle(args.fTexSamplers[0]).c_str()); fragBuilder->codeAppendf( - "0.5)).%s.w;\n half vcoord = half((abs(translatedPos.y - 0.5 * height) - 0.5 * " - "wh.y) / float(%s));\n half vlookup = texture(%s, float2(float(vcoord), " - "0.5)).%s.w;\n %s = (%s * hlookup) * vlookup;\n} else {\n half2 " - "translatedPos = half2(sk_FragCoord.xy - %s.xy);\n half width = half(%s.z - " - "%s.x);\n half height = half(%s.w - %s.y);\n half2 smallDims = half2(width - " - "%s, height - %s);\n half center = half(2.0 * floor(float(float(%s / 2.0) + " - "0.25)) - 1.0);\n half2 wh = smallDims - half2(f", - fragBuilder->getProgramBuilder()->samplerSwizzle(args.fTexSamplers[0]).c_str(), + ";\n half vcoord = half((abs(translatedPos.y - 0.5 * height) - 0.5 * wh.y) / " + "float(%s));\n half vlookup = texture(%s, float2(float(vcoord), 0.5)).%s.w;\n " + " %s = (%s * hlookup) * vlookup;\n} else {\n half2 translatedPos = " + "half2(sk_FragCoord.xy - %s.xy);\n half width = half(%s.z - %s.x);\n half " + "height = half(%s.w - %s.y);\n half2 smallDims = half2(width - %s, height - " + "%s);\n half center = half(2.0 * floor(float(float(%s / 2.0) + 0.25)) - 1.0);\n " + " half2 wh = smallDims - half2(float2(floa", args.fUniformHandler->getUniformCStr(fProfileSizeVar), fragBuilder->getProgramBuilder()->samplerVariable(args.fTexSamplers[0]).c_str(), fragBuilder->getProgramBuilder()->samplerSwizzle(args.fTexSamplers[0]).c_str(), @@ -85,7 +85,7 @@ public: args.fUniformHandler->getUniformCStr(fProfileSizeVar), args.fUniformHandler->getUniformCStr(fProfileSizeVar)); fragBuilder->codeAppendf( - "loat2(float(center), float(center)));\n half hcoord = " + "t(center), float(center)));\n half hcoord = " "half((abs(float(float(translatedPos.x) - 0.5 * float(width))) - 0.5 * " "float(wh.x)) / float(%s));\n half hlookup = texture(%s, float2(float(hcoord), " "0.5)).%s.w;\n half vcoord = half((abs(float(float(translatedPos.y) - 0.5 * " diff --git a/src/gpu/effects/GrSkSLFP.cpp b/src/gpu/effects/GrSkSLFP.cpp deleted file mode 100644 index bc84c833d7..0000000000 --- a/src/gpu/effects/GrSkSLFP.cpp +++ /dev/null @@ -1,268 +0,0 @@ -/* - * Copyright 2018 Google Inc. - * - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -#include "GrSkSLFP.h" -#include "glsl/GrGLSLFragmentProcessor.h" -#include "glsl/GrGLSLFragmentShaderBuilder.h" -#include "glsl/GrGLSLProgramBuilder.h" -#include "GrContext.h" -#include "GrContextPriv.h" -#include "GrTexture.h" -#include "SkSLUtil.h" - -GrSkSLFPFactory::GrSkSLFPFactory(const char* name, const GrShaderCaps* shaderCaps, const char* sksl) - : fName(name) { - SkSL::Program::Settings settings; - settings.fCaps = shaderCaps; - fBaseProgram = fCompiler.convertProgram(SkSL::Program::kPipelineStage_Kind, - SkSL::String(sksl), - settings); - if (fCompiler.errorCount()) { - SkDebugf("%s\n", fCompiler.errorText().c_str()); - } - SkASSERT(fBaseProgram); - SkASSERT(!fCompiler.errorCount()); - for (const auto& e : *fBaseProgram) { - if (e.fKind == SkSL::ProgramElement::kVar_Kind) { - SkSL::VarDeclarations& v = (SkSL::VarDeclarations&) e; - for (const auto& varStatement : v.fVars) { - const SkSL::Variable& var = *((SkSL::VarDeclaration&) *varStatement).fVar; - if (var.fModifiers.fFlags & SkSL::Modifiers::kIn_Flag) { - fInputVars.push_back(&var); - } - if (var.fModifiers.fLayout.fKey) { - fKeyVars.push_back(&var); - } - } - } - } -} - -const SkSL::Program* GrSkSLFPFactory::getSpecialization(const SkSL::String& key, const void* inputs, - size_t inputSize) { - const auto& found = fSpecializations.find(key); - if (found != fSpecializations.end()) { - return found->second.get(); - } - - std::unordered_map<SkSL::String, SkSL::Program::Settings::Value> inputMap; - size_t offset = 0; - for (const auto& v : fInputVars) { - SkSL::String name(v->fName); - if (&v->fType == fCompiler.context().fInt_Type.get()) { - offset = SkAlign4(offset); - int32_t v = *(int32_t*) (((uint8_t*) inputs) + offset); - inputMap.insert(std::make_pair(name, SkSL::Program::Settings::Value(v))); - offset += sizeof(int32_t); - } - } - SkASSERT(offset == inputSize); - - std::unique_ptr<SkSL::Program> specialized = fCompiler.specialize(*fBaseProgram, inputMap); - SkAssertResult(fCompiler.optimize(*specialized)); - const SkSL::Program* result = specialized.get(); - fSpecializations.insert(std::make_pair(key, std::move(specialized))); - return result; -} - -class GrGLSLSkSLFP : public GrGLSLFragmentProcessor { -public: - GrGLSLSkSLFP(SkSL::String glsl, std::vector<SkSL::Compiler::FormatArg> formatArgs) - : fGLSL(glsl) - , fFormatArgs(formatArgs) {} - - void emitCode(EmitArgs& args) override { - GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder; - int substringStartIndex = 0; - int formatArgIndex = 0; - for (size_t i = 0; i < fGLSL.length(); ++i) { - char c = fGLSL[i]; - if (c == '%') { - fragBuilder->codeAppend(fGLSL.c_str() + substringStartIndex, - i - substringStartIndex); - ++i; - c = fGLSL[i]; - switch (c) { - case 's': - switch (fFormatArgs[formatArgIndex++]) { - case SkSL::Compiler::FormatArg::kInput: - fragBuilder->codeAppend(args.fInputColor ? args.fInputColor - : "half4(1)"); - break; - case SkSL::Compiler::FormatArg::kOutput: - fragBuilder->codeAppend(args.fOutputColor); - break; - } - break; - default: - fragBuilder->codeAppendf("%c", c); - } - substringStartIndex = i + 1; - } - } - fragBuilder->codeAppend(fGLSL.c_str() + substringStartIndex, - fGLSL.length() - substringStartIndex); - } - - // nearly-finished GLSL; still contains printf-style "%s" format tokens - const SkSL::String fGLSL; - std::vector<SkSL::Compiler::FormatArg> fFormatArgs; -}; - -std::unique_ptr<GrFragmentProcessor> GrSkSLFP::Make(GrContext* context, int index, const char* name, - const char* sksl, const void* inputs, - size_t inputSize) { - return std::unique_ptr<GrFragmentProcessor>(new GrSkSLFP( - context->contextPriv().getFPFactoryCache(), - context->contextPriv().caps()->shaderCaps(), - index, name, sksl, inputs, inputSize)); -} - - -GrSkSLFP::GrSkSLFP(sk_sp<GrSkSLFPFactoryCache> factoryCache, const GrShaderCaps* shaderCaps, - int index, const char* name, const char* sksl, const void* inputs, - size_t inputSize) - : INHERITED(kGrSkSLFP_ClassID, kNone_OptimizationFlags) - , fFactoryCache(factoryCache) - , fShaderCaps(sk_ref_sp(shaderCaps)) - , fIndex(index) - , fName(name) - , fSkSL(sksl) - , fInputs(new int8_t[inputSize]) - , fInputSize(inputSize) { - memcpy(fInputs.get(), inputs, inputSize); -} - -GrSkSLFP::GrSkSLFP(const GrSkSLFP& other) - : INHERITED(kGrSkSLFP_ClassID, kNone_OptimizationFlags) - , fFactoryCache(other.fFactoryCache) - , fShaderCaps(other.fShaderCaps) - , fFactory(other.fFactory) - , fIndex(other.fIndex) - , fName(other.fName) - , fSkSL(other.fSkSL) - , fInputs(new int8_t[other.fInputSize]) - , fInputSize(other.fInputSize) { - memcpy(fInputs.get(), other.fInputs.get(), fInputSize); -} - -const char* GrSkSLFP::name() const { - return fName; -} - -void GrSkSLFP::createFactory() const { - if (!fFactory) { - fFactory = fFactoryCache->get(fIndex); - if (!fFactory) { - fFactory = sk_sp<GrSkSLFPFactory>(new GrSkSLFPFactory(fName, fShaderCaps.get(), fSkSL)); - fFactoryCache->set(fIndex, fFactory); - } - } -} - -GrGLSLFragmentProcessor* GrSkSLFP::onCreateGLSLInstance() const { - this->createFactory(); - const SkSL::Program* specialized = fFactory->getSpecialization(fKey, fInputs.get(), fInputSize); - SkSL::String glsl; - std::vector<SkSL::Compiler::FormatArg> formatArgs; - if (!fFactory->fCompiler.toPipelineStage(*specialized, &glsl, &formatArgs)) { - printf("%s\n", fFactory->fCompiler.errorText().c_str()); - abort(); - } - return new GrGLSLSkSLFP(glsl, formatArgs); -} - -void GrSkSLFP::onGetGLSLProcessorKey(const GrShaderCaps& caps, - GrProcessorKeyBuilder* b) const { - this->createFactory(); - size_t offset = 0; - char* inputs = (char*) fInputs.get(); - for (const auto& v : fFactory->fInputVars) { - if (&v->fType == fFactory->fCompiler.context().fInt_Type.get()) { - offset = SkAlign4(offset); - if (v->fModifiers.fLayout.fKey) { - fKey += inputs[offset + 0]; - fKey += inputs[offset + 1]; - fKey += inputs[offset + 2]; - fKey += inputs[offset + 3]; - b->add32(*(int32_t*) (inputs + offset)); - } - offset += sizeof(int32_t); - } - else { - // unsupported input var type - SkASSERT(false); - } - } - SkASSERT(offset == fInputSize); -} - -bool GrSkSLFP::onIsEqual(const GrFragmentProcessor& other) const { - const GrSkSLFP& sk = other.cast<GrSkSLFP>(); - SkASSERT(fIndex != sk.fIndex || fInputSize == sk.fInputSize); - return fIndex == sk.fIndex && - !memcmp(fInputs.get(), sk.fInputs.get(), fInputSize); -} - -std::unique_ptr<GrFragmentProcessor> GrSkSLFP::clone() const { - return std::unique_ptr<GrFragmentProcessor>(new GrSkSLFP(*this)); -} - -// We have to do a bit of manual refcounting in the cache methods below. Ideally, we could just -// define fFactories to contain sk_sp<GrSkSLFPFactory> rather than GrSkSLFPFactory*, but that would -// require GrContext to include GrSkSLFP, which creates much bigger headaches than a few manual -// refcounts. - -sk_sp<GrSkSLFPFactory> GrSkSLFPFactoryCache::get(int index) { - if (index >= (int) fFactories.size()) { - return nullptr; - } - GrSkSLFPFactory* result = fFactories[index]; - result->ref(); - return sk_sp<GrSkSLFPFactory>(result); -} - -void GrSkSLFPFactoryCache::set(int index, sk_sp<GrSkSLFPFactory> factory) { - while (index >= (int) fFactories.size()) { - fFactories.emplace_back(); - } - factory->ref(); - SkASSERT(!fFactories[index]); - fFactories[index] = factory.get(); -} - -GrSkSLFPFactoryCache::~GrSkSLFPFactoryCache() { - for (GrSkSLFPFactory* factory : fFactories) { - if (factory) { - factory->unref(); - } - } -} - -GR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrSkSLFP); - -#if GR_TEST_UTILS - -#include "SkGr.h" - -using Value = SkSL::Program::Settings::Value; - -std::unique_ptr<GrFragmentProcessor> GrSkSLFP::TestCreate(GrProcessorTestData* d) { - int type = d->fRandom->nextULessThan(1); - switch (type) { - case 0: { - static int ditherIndex = NewIndex(); - int rangeType = d->fRandom->nextULessThan(3); - return GrSkSLFP::Make(d->context(), ditherIndex, "Dither", SKSL_DITHER_SRC, &rangeType, - sizeof(rangeType)); - } - } - SK_ABORT("unreachable"); - return nullptr; -} - -#endif diff --git a/src/gpu/effects/GrSkSLFP.h b/src/gpu/effects/GrSkSLFP.h deleted file mode 100644 index 428e0892e0..0000000000 --- a/src/gpu/effects/GrSkSLFP.h +++ /dev/null @@ -1,147 +0,0 @@ -/* - * Copyright 2018 Google Inc. - * - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -#ifndef GrSkSLFP_DEFINED -#define GrSkSLFP_DEFINED - -#include "GrCaps.h" -#include "GrFragmentProcessor.h" -#include "GrCoordTransform.h" -#include "GrShaderCaps.h" -#include "SkSLCompiler.h" -#include "SkSLPipelineStageCodeGenerator.h" -#include "SkRefCnt.h" -#include "../private/GrSkSLFPFactoryCache.h" - -class GrContext; -class GrSkSLFPFactory; - -class GrSkSLFP : public GrFragmentProcessor { -public: - /** - * Returns a new unique identifier. Each different SkSL fragment processor should call - * NewIndex once, statically, and use this index for all calls to Make. - */ - static int NewIndex() { - static int index = 0; - return sk_atomic_inc(&index); - } - - /** - * Creates a new fragment processor from an SkSL source string and a struct of inputs to the - * program. The input struct's type is derived from the 'in' variables in the SkSL source, so - * e.g. the shader: - * - * in bool dither; - * in float x; - * in float y; - * .... - * - * would expect a pointer to a struct set up like: - * - * struct { - * bool dither; - * float x; - * float y; - * }; - * - * As turning SkSL into GLSL / SPIR-V / etc. is fairly expensive, and the output may differ - * based on the inputs, internally the process is divided into two steps: we first parse and - * semantically analyze the SkSL into an internal representation, and then "specialize" this - * internal representation based on the inputs. The unspecialized internal representation of - * the program is cached, so further specializations of the same code are much faster than the - * first call. - * - * This caching is based on the 'index' parameter, which should be derived by statically calling - * 'NewIndex()'. Each given SkSL string should have a single, statically defined index - * associated with it. - */ - static std::unique_ptr<GrFragmentProcessor> Make( - GrContext* context, - int index, - const char* name, - const char* sksl, - const void* inputs, - size_t inputSize); - - const char* name() const override; - - std::unique_ptr<GrFragmentProcessor> clone() const override; - -private: - GrSkSLFP(sk_sp<GrSkSLFPFactoryCache> factoryCache, const GrShaderCaps* shaderCaps, int fIndex, - const char* name, const char* sksl, const void* inputs, size_t inputSize); - - GrSkSLFP(const GrSkSLFP& other); - - GrGLSLFragmentProcessor* onCreateGLSLInstance() const override; - - void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override; - - bool onIsEqual(const GrFragmentProcessor&) const override; - - void createFactory() const; - - sk_sp<GrSkSLFPFactoryCache> fFactoryCache; - - const sk_sp<GrShaderCaps> fShaderCaps; - - mutable sk_sp<GrSkSLFPFactory> fFactory; - - int fIndex; - - const char* fName; - - const char* fSkSL; - - const std::unique_ptr<int8_t[]> fInputs; - - size_t fInputSize; - - mutable SkSL::String fKey; - - GR_DECLARE_FRAGMENT_PROCESSOR_TEST - - typedef GrFragmentProcessor INHERITED; - - friend class GrSkSLFPFactory; -}; - -/** - * Produces GrFragmentProcessors from SkSL code. As the shader code produced from the SkSL depends - * upon the inputs to the SkSL (static if's, etc.) we first create a factory for a given SkSL - * string, then use that to create the actual GrFragmentProcessor. - */ -class GrSkSLFPFactory : public SkNVRefCnt<GrSkSLFPFactory> { -public: - /** - * Constructs a GrSkSLFPFactory for a given SkSL source string. Creating a factory will - * preprocess the SkSL and determine which of its inputs are declared "key" (meaning they cause - * the produced shaders to differ), so it is important to reuse the same factory instance for - * the same shader in order to avoid repeatedly re-parsing the SkSL. - */ - GrSkSLFPFactory(const char* name, const GrShaderCaps* shaderCaps, const char* sksl); - - const SkSL::Program* getSpecialization(const SkSL::String& key, const void* inputs, - size_t inputSize); - - const char* fName; - - SkSL::Compiler fCompiler; - - std::shared_ptr<SkSL::Program> fBaseProgram; - - std::vector<const SkSL::Variable*> fInputVars; - - std::vector<const SkSL::Variable*> fKeyVars; - - std::unordered_map<SkSL::String, std::unique_ptr<const SkSL::Program>> fSpecializations; - - friend class GrSkSLFP; -}; - -#endif diff --git a/src/gpu/glsl/GrGLSLShaderBuilder.h b/src/gpu/glsl/GrGLSLShaderBuilder.h index f61174f2d7..538300d95a 100644 --- a/src/gpu/glsl/GrGLSLShaderBuilder.h +++ b/src/gpu/glsl/GrGLSLShaderBuilder.h @@ -102,8 +102,6 @@ public: void codeAppend(const char* str) { this->code().append(str); } - void codeAppend(const char* str, size_t length) { this->code().append(str, length); } - void codePrependf(const char format[], ...) SK_PRINTF_LIKE(2, 3) { va_list args; va_start(args, format); |