aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/gpu
diff options
context:
space:
mode:
authorGravatar Ethan Nicholas <ethannicholas@google.com>2018-07-19 20:10:37 +0000
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2018-07-19 20:10:46 +0000
commit6c48e4d11ce80fa5cfef56e13b2d5847fe94a7cc (patch)
tree57e5d832d16aa9a0447e5102fe9811e39f8403d9 /src/gpu
parent736db1081b378ac8c167dfbc0322470d28c1cb3e (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.cpp9
-rw-r--r--src/gpu/GrContextPriv.h5
-rw-r--r--src/gpu/GrContextThreadSafeProxyPriv.h1
-rw-r--r--src/gpu/GrDDLContext.cpp2
-rw-r--r--src/gpu/GrDirectContext.cpp6
-rw-r--r--src/gpu/GrProcessor.h1
-rw-r--r--src/gpu/SkGr.cpp86
-rw-r--r--src/gpu/SkGr.h2
-rw-r--r--src/gpu/effects/GrDitherEffect.cpp75
-rw-r--r--src/gpu/effects/GrDitherEffect.fp85
-rw-r--r--src/gpu/effects/GrDitherEffect.h67
-rw-r--r--src/gpu/effects/GrRectBlurEffect.cpp34
-rw-r--r--src/gpu/effects/GrSkSLFP.cpp268
-rw-r--r--src/gpu/effects/GrSkSLFP.h147
-rw-r--r--src/gpu/glsl/GrGLSLShaderBuilder.h2
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);