diff options
author | Ethan Nicholas <ethannicholas@google.com> | 2017-07-19 13:54:20 -0400 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2017-07-19 18:19:55 +0000 |
commit | b7e8c3b52a306357ecd08d00170062137ec641d4 (patch) | |
tree | 8041288e1b622f09c2f964ec4a5209832dff734c /src/effects | |
parent | e5b399ee69332e0d68a660d6695d1182a4cb16b1 (diff) |
run skslc output through clang-format
Bug: skia:
Change-Id: I97af420d1c3270e24e5d0959237b8163faa9e069
Reviewed-on: https://skia-review.googlesource.com/24646
Reviewed-by: Brian Osman <brianosman@google.com>
Commit-Queue: Ethan Nicholas <ethannicholas@google.com>
Diffstat (limited to 'src/effects')
-rw-r--r-- | src/effects/GrAlphaThresholdFragmentProcessor.cpp | 97 | ||||
-rw-r--r-- | src/effects/GrAlphaThresholdFragmentProcessor.h | 49 | ||||
-rw-r--r-- | src/effects/GrCircleBlurFragmentProcessor.cpp | 447 | ||||
-rw-r--r-- | src/effects/GrCircleBlurFragmentProcessor.h | 21 |
4 files changed, 310 insertions, 304 deletions
diff --git a/src/effects/GrAlphaThresholdFragmentProcessor.cpp b/src/effects/GrAlphaThresholdFragmentProcessor.cpp index f400777e24..6de452bfa1 100644 --- a/src/effects/GrAlphaThresholdFragmentProcessor.cpp +++ b/src/effects/GrAlphaThresholdFragmentProcessor.cpp @@ -11,15 +11,15 @@ #include "GrAlphaThresholdFragmentProcessor.h" #if SK_SUPPORT_GPU - inline GrFragmentProcessor::OptimizationFlags GrAlphaThresholdFragmentProcessor::optFlags( - float outerThreshold) { - if (outerThreshold >= 1.0) { - return kPreservesOpaqueInput_OptimizationFlag | - kCompatibleWithCoverageAsAlpha_OptimizationFlag; - } else { - return kCompatibleWithCoverageAsAlpha_OptimizationFlag; - } +inline GrFragmentProcessor::OptimizationFlags GrAlphaThresholdFragmentProcessor::optFlags( + float outerThreshold) { + if (outerThreshold >= 1.0) { + return kPreservesOpaqueInput_OptimizationFlag | + kCompatibleWithCoverageAsAlpha_OptimizationFlag; + } else { + return kCompatibleWithCoverageAsAlpha_OptimizationFlag; } +} #include "glsl/GrGLSLColorSpaceXformHelper.h" #include "glsl/GrGLSLFragmentProcessor.h" #include "glsl/GrGLSLFragmentShaderBuilder.h" @@ -31,24 +31,57 @@ public: GrGLSLAlphaThresholdFragmentProcessor() {} void emitCode(EmitArgs& args) override { GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder; - const GrAlphaThresholdFragmentProcessor& _outer = args.fFp.cast<GrAlphaThresholdFragmentProcessor>(); - (void) _outer; + const GrAlphaThresholdFragmentProcessor& _outer = + args.fFp.cast<GrAlphaThresholdFragmentProcessor>(); + (void)_outer; fColorSpaceHelper.emitCode(args.fUniformHandler, _outer.colorXform().get()); - fInnerThresholdVar = args.fUniformHandler->addUniform(kFragment_GrShaderFlag, kFloat_GrSLType, kDefault_GrSLPrecision, "innerThreshold"); - fOuterThresholdVar = args.fUniformHandler->addUniform(kFragment_GrShaderFlag, kFloat_GrSLType, kDefault_GrSLPrecision, "outerThreshold"); - SkSL::String sk_TransformedCoords2D_0 = fragBuilder->ensureCoords2D(args.fTransformedCoords[0]); - SkSL::String sk_TransformedCoords2D_1 = fragBuilder->ensureCoords2D(args.fTransformedCoords[1]); - fragBuilder->codeAppendf("vec4 _tmpVar1;vec4 color = %stexture(%s, %s).%s%s;\nvec4 mask_color = texture(%s, %s).%s;\nif (mask_color.w < 0.5) {\n if (color.w > %s) {\n float scale = %s / color.w;\n color.xyz *= scale;\n color.w = %s;\n }\n} else if (color.w < %s) {\n float scale = %s / max(0.001, color.w);\n color.xyz *= scale;\n color.w = %s;\n}\n%s = color;\n", fColorSpaceHelper.isValid() ? "(_tmpVar1 = " : "", fragBuilder->getProgramBuilder()->samplerVariable(args.fTexSamplers[0]).c_str(), sk_TransformedCoords2D_0.c_str(), fragBuilder->getProgramBuilder()->samplerSwizzle(args.fTexSamplers[0]).c_str(), fColorSpaceHelper.isValid() ? SkStringPrintf(", vec4(clamp((%s * vec4(_tmpVar1.rgb, 1.0)).rgb, 0.0, _tmpVar1.a), _tmpVar1.a))", args.fUniformHandler->getUniformCStr(fColorSpaceHelper.gamutXformUniform())).c_str() : "", fragBuilder->getProgramBuilder()->samplerVariable(args.fTexSamplers[1]).c_str(), sk_TransformedCoords2D_1.c_str(), fragBuilder->getProgramBuilder()->samplerSwizzle(args.fTexSamplers[1]).c_str(), args.fUniformHandler->getUniformCStr(fOuterThresholdVar), args.fUniformHandler->getUniformCStr(fOuterThresholdVar), args.fUniformHandler->getUniformCStr(fOuterThresholdVar), args.fUniformHandler->getUniformCStr(fInnerThresholdVar), args.fUniformHandler->getUniformCStr(fInnerThresholdVar), args.fUniformHandler->getUniformCStr(fInnerThresholdVar), args.fOutputColor); + fInnerThresholdVar = args.fUniformHandler->addUniform( + kFragment_GrShaderFlag, kFloat_GrSLType, kDefault_GrSLPrecision, "innerThreshold"); + fOuterThresholdVar = args.fUniformHandler->addUniform( + kFragment_GrShaderFlag, kFloat_GrSLType, kDefault_GrSLPrecision, "outerThreshold"); + SkSL::String sk_TransformedCoords2D_0 = + fragBuilder->ensureCoords2D(args.fTransformedCoords[0]); + SkSL::String sk_TransformedCoords2D_1 = + fragBuilder->ensureCoords2D(args.fTransformedCoords[1]); + fragBuilder->codeAppendf( + "vec4 _tmpVar1;vec4 color = %stexture(%s, %s).%s%s;\nvec4 mask_color = texture(%s, " + "%s).%s;\nif (mask_color.w < 0.5) {\n if (color.w > %s) {\n float scale " + "= %s / color.w;\n color.xyz *= scale;\n color.w = %s;\n }\n} " + "else if (color.w < %s) {\n float scale = %s / max(0.001, color.w);\n " + "color.xyz *= scale;\n color.w = %s;\n}\n%s = color;\n", + fColorSpaceHelper.isValid() ? "(_tmpVar1 = " : "", + fragBuilder->getProgramBuilder()->samplerVariable(args.fTexSamplers[0]).c_str(), + sk_TransformedCoords2D_0.c_str(), + fragBuilder->getProgramBuilder()->samplerSwizzle(args.fTexSamplers[0]).c_str(), + fColorSpaceHelper.isValid() + ? SkStringPrintf(", vec4(clamp((%s * vec4(_tmpVar1.rgb, 1.0)).rgb, 0.0, " + "_tmpVar1.a), _tmpVar1.a))", + args.fUniformHandler->getUniformCStr( + fColorSpaceHelper.gamutXformUniform())) + .c_str() + : "", + fragBuilder->getProgramBuilder()->samplerVariable(args.fTexSamplers[1]).c_str(), + sk_TransformedCoords2D_1.c_str(), + fragBuilder->getProgramBuilder()->samplerSwizzle(args.fTexSamplers[1]).c_str(), + args.fUniformHandler->getUniformCStr(fOuterThresholdVar), + args.fUniformHandler->getUniformCStr(fOuterThresholdVar), + args.fUniformHandler->getUniformCStr(fOuterThresholdVar), + args.fUniformHandler->getUniformCStr(fInnerThresholdVar), + args.fUniformHandler->getUniformCStr(fInnerThresholdVar), + args.fUniformHandler->getUniformCStr(fInnerThresholdVar), args.fOutputColor); } + private: - void onSetData(const GrGLSLProgramDataManager& pdman, const GrFragmentProcessor& _proc) override { - const GrAlphaThresholdFragmentProcessor& _outer = _proc.cast<GrAlphaThresholdFragmentProcessor>(); + void onSetData(const GrGLSLProgramDataManager& pdman, + const GrFragmentProcessor& _proc) override { + const GrAlphaThresholdFragmentProcessor& _outer = + _proc.cast<GrAlphaThresholdFragmentProcessor>(); { - if (fColorSpaceHelper.isValid()) { - fColorSpaceHelper.setData(pdman, _outer.colorXform().get()); - } - pdman.set1f(fInnerThresholdVar, _outer.innerThreshold()); - pdman.set1f(fOuterThresholdVar, _outer.outerThreshold()); + if (fColorSpaceHelper.isValid()) { + fColorSpaceHelper.setData(pdman, _outer.colorXform().get()); + } + pdman.set1f(fInnerThresholdVar, _outer.innerThreshold()); + pdman.set1f(fOuterThresholdVar, _outer.outerThreshold()); } } UniformHandle fImageVar; @@ -60,12 +93,13 @@ private: GrGLSLFragmentProcessor* GrAlphaThresholdFragmentProcessor::onCreateGLSLInstance() const { return new GrGLSLAlphaThresholdFragmentProcessor(); } -void GrAlphaThresholdFragmentProcessor::onGetGLSLProcessorKey(const GrShaderCaps& caps, GrProcessorKeyBuilder* b) const { +void GrAlphaThresholdFragmentProcessor::onGetGLSLProcessorKey(const GrShaderCaps& caps, + GrProcessorKeyBuilder* b) const { b->add32(GrColorSpaceXform::XformKey(fColorXform.get())); } bool GrAlphaThresholdFragmentProcessor::onIsEqual(const GrFragmentProcessor& other) const { const GrAlphaThresholdFragmentProcessor& that = other.cast<GrAlphaThresholdFragmentProcessor>(); - (void) that; + (void)that; if (fImage != that.fImage) return false; if (fColorXform != that.fColorXform) return false; if (fMask != that.fMask) return false; @@ -75,11 +109,11 @@ bool GrAlphaThresholdFragmentProcessor::onIsEqual(const GrFragmentProcessor& oth } GR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrAlphaThresholdFragmentProcessor); #if GR_TEST_UTILS -sk_sp<GrFragmentProcessor> GrAlphaThresholdFragmentProcessor::TestCreate(GrProcessorTestData* testData) { - +sk_sp<GrFragmentProcessor> GrAlphaThresholdFragmentProcessor::TestCreate( + GrProcessorTestData* testData) { sk_sp<GrTextureProxy> bmpProxy = testData->textureProxy(GrProcessorUnitTest::kSkiaPMTextureIdx); sk_sp<GrTextureProxy> maskProxy = testData->textureProxy(GrProcessorUnitTest::kAlphaTextureIdx); - + float innerThresh = testData->fRandom->nextUScalar1() * .99f + 0.005f; float outerThresh = testData->fRandom->nextUScalar1() * .99f + 0.005f; const int kMaxWidth = 1000; @@ -90,12 +124,9 @@ sk_sp<GrFragmentProcessor> GrAlphaThresholdFragmentProcessor::TestCreate(GrProce uint32_t y = testData->fRandom->nextULessThan(kMaxHeight - height); SkIRect bounds = SkIRect::MakeXYWH(x, y, width, height); sk_sp<GrColorSpaceXform> colorSpaceXform = GrTest::TestColorXform(testData->fRandom); - return GrAlphaThresholdFragmentProcessor::Make( - std::move(bmpProxy), - colorSpaceXform, - std::move(maskProxy), - innerThresh, outerThresh, - bounds); + return GrAlphaThresholdFragmentProcessor::Make(std::move(bmpProxy), colorSpaceXform, + std::move(maskProxy), innerThresh, outerThresh, + bounds); } #endif #endif diff --git a/src/effects/GrAlphaThresholdFragmentProcessor.h b/src/effects/GrAlphaThresholdFragmentProcessor.h index 5dd669ac14..3bc42a7ddd 100644 --- a/src/effects/GrAlphaThresholdFragmentProcessor.h +++ b/src/effects/GrAlphaThresholdFragmentProcessor.h @@ -13,49 +13,46 @@ #include "SkTypes.h" #if SK_SUPPORT_GPU - #include "GrColorSpaceXform.h" +#include "GrColorSpaceXform.h" #include "GrFragmentProcessor.h" #include "GrCoordTransform.h" #include "GrColorSpaceXform.h" #include "effects/GrProxyMove.h" class GrAlphaThresholdFragmentProcessor : public GrFragmentProcessor { public: - inline OptimizationFlags optFlags(float outerThreshold); sk_sp<GrColorSpaceXform> colorXform() const { return fColorXform; } float innerThreshold() const { return fInnerThreshold; } float outerThreshold() const { return fOuterThreshold; } static sk_sp<GrFragmentProcessor> Make(sk_sp<GrTextureProxy> image, - sk_sp<GrColorSpaceXform> colorXform, - sk_sp<GrTextureProxy> mask, + sk_sp<GrColorSpaceXform> + colorXform, + sk_sp<GrTextureProxy> + mask, float innerThreshold, float outerThreshold, const SkIRect& bounds) { - return sk_sp<GrFragmentProcessor>(new GrAlphaThresholdFragmentProcessor(image, - colorXform, - mask, - innerThreshold, - outerThreshold, - bounds)); + return sk_sp<GrFragmentProcessor>(new GrAlphaThresholdFragmentProcessor( + image, colorXform, mask, innerThreshold, outerThreshold, bounds)); } const char* name() const override { return "AlphaThresholdFragmentProcessor"; } + private: - GrAlphaThresholdFragmentProcessor(sk_sp<GrTextureProxy> image, sk_sp<GrColorSpaceXform> colorXform, sk_sp<GrTextureProxy> mask, float innerThreshold, float outerThreshold, - const SkIRect& bounds -) - : INHERITED(kNone_OptimizationFlags) - , fImage(std::move(image)) - , fColorXform(colorXform) - , fMask(std::move(mask)) - , fInnerThreshold(innerThreshold) - , fOuterThreshold(outerThreshold) - , fImageCoordTransform( - SkMatrix::I() -, fImage.proxy()) - , fMaskCoordTransform( - SkMatrix::MakeTrans(SkIntToScalar(-bounds.x()), SkIntToScalar(-bounds.y())) -, fMask.proxy()) { + GrAlphaThresholdFragmentProcessor(sk_sp<GrTextureProxy> image, + sk_sp<GrColorSpaceXform> colorXform, + sk_sp<GrTextureProxy> mask, float innerThreshold, + float outerThreshold, const SkIRect& bounds) + : INHERITED(kNone_OptimizationFlags) + , fImage(std::move(image)) + , fColorXform(colorXform) + , fMask(std::move(mask)) + , fInnerThreshold(innerThreshold) + , fOuterThreshold(outerThreshold) + , fImageCoordTransform(SkMatrix::I(), fImage.proxy()) + , fMaskCoordTransform( + SkMatrix::MakeTrans(SkIntToScalar(-bounds.x()), SkIntToScalar(-bounds.y())), + fMask.proxy()) { this->addTextureSampler(&fImage); this->addTextureSampler(&fMask); this->addCoordTransform(&fImageCoordTransform); @@ -63,7 +60,7 @@ private: this->initClassID<GrAlphaThresholdFragmentProcessor>(); } GrGLSLFragmentProcessor* onCreateGLSLInstance() const override; - void onGetGLSLProcessorKey(const GrShaderCaps&,GrProcessorKeyBuilder*) const override; + void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override; bool onIsEqual(const GrFragmentProcessor&) const override; GR_DECLARE_FRAGMENT_PROCESSOR_TEST TextureSampler fImage; diff --git a/src/effects/GrCircleBlurFragmentProcessor.cpp b/src/effects/GrCircleBlurFragmentProcessor.cpp index 5759fc47cf..135b00e4d9 100644 --- a/src/effects/GrCircleBlurFragmentProcessor.cpp +++ b/src/effects/GrCircleBlurFragmentProcessor.cpp @@ -11,248 +11,211 @@ #include "GrCircleBlurFragmentProcessor.h" #if SK_SUPPORT_GPU - #include "GrResourceProvider.h" - - - - static float make_unnormalized_half_kernel(float* halfKernel, int halfKernelSize, float sigma) { - const float invSigma = 1.f / sigma; - const float b = -0.5f * invSigma * invSigma; - float tot = 0.0f; - - float t = 0.5f; - for (int i = 0; i < halfKernelSize; ++i) { - float value = expf(t * t * b); - tot += value; - halfKernel[i] = value; - t += 1.f; - } - return tot; +#include "GrResourceProvider.h" + +static float make_unnormalized_half_kernel(float* halfKernel, int halfKernelSize, float sigma) { + const float invSigma = 1.f / sigma; + const float b = -0.5f * invSigma * invSigma; + float tot = 0.0f; + + float t = 0.5f; + for (int i = 0; i < halfKernelSize; ++i) { + float value = expf(t * t * b); + tot += value; + halfKernel[i] = value; + t += 1.f; } + return tot; +} - - - static void make_half_kernel_and_summed_table(float* halfKernel, float* summedHalfKernel, - int halfKernelSize, float sigma) { - - const float tot = 2.f * make_unnormalized_half_kernel(halfKernel, halfKernelSize, sigma); - float sum = 0.f; - for (int i = 0; i < halfKernelSize; ++i) { - halfKernel[i] /= tot; - sum += halfKernel[i]; - summedHalfKernel[i] = sum; - } +static void make_half_kernel_and_summed_table(float* halfKernel, float* summedHalfKernel, + int halfKernelSize, float sigma) { + const float tot = 2.f * make_unnormalized_half_kernel(halfKernel, halfKernelSize, sigma); + float sum = 0.f; + for (int i = 0; i < halfKernelSize; ++i) { + halfKernel[i] /= tot; + sum += halfKernel[i]; + summedHalfKernel[i] = sum; } +} - - - void apply_kernel_in_y(float* results, int numSteps, float firstX, float circleR, - int halfKernelSize, const float* summedHalfKernelTable) { - float x = firstX; - for (int i = 0; i < numSteps; ++i, x += 1.f) { - if (x < -circleR || x > circleR) { - results[i] = 0; - continue; - } - float y = sqrtf(circleR * circleR - x * x); - - - y -= 0.5f; - int yInt = SkScalarFloorToInt(y); - SkASSERT(yInt >= -1); - if (y < 0) { - results[i] = (y + 0.5f) * summedHalfKernelTable[0]; - } else if (yInt >= halfKernelSize - 1) { - results[i] = 0.5f; - } else { - float yFrac = y - yInt; - results[i] = (1.f - yFrac) * summedHalfKernelTable[yInt] + - yFrac * summedHalfKernelTable[yInt + 1]; - } +void apply_kernel_in_y(float* results, int numSteps, float firstX, float circleR, + int halfKernelSize, const float* summedHalfKernelTable) { + float x = firstX; + for (int i = 0; i < numSteps; ++i, x += 1.f) { + if (x < -circleR || x > circleR) { + results[i] = 0; + continue; + } + float y = sqrtf(circleR * circleR - x * x); + + y -= 0.5f; + int yInt = SkScalarFloorToInt(y); + SkASSERT(yInt >= -1); + if (y < 0) { + results[i] = (y + 0.5f) * summedHalfKernelTable[0]; + } else if (yInt >= halfKernelSize - 1) { + results[i] = 0.5f; + } else { + float yFrac = y - yInt; + results[i] = (1.f - yFrac) * summedHalfKernelTable[yInt] + + yFrac * summedHalfKernelTable[yInt + 1]; } } +} - - - - - static uint8_t eval_at(float evalX, float circleR, const float* halfKernel, int halfKernelSize, - const float* yKernelEvaluations) { - float acc = 0; - - float x = evalX - halfKernelSize; - for (int i = 0; i < halfKernelSize; ++i, x += 1.f) { - if (x < -circleR || x > circleR) { - continue; - } - float verticalEval = yKernelEvaluations[i]; - acc += verticalEval * halfKernel[halfKernelSize - i - 1]; +static uint8_t eval_at(float evalX, float circleR, const float* halfKernel, int halfKernelSize, + const float* yKernelEvaluations) { + float acc = 0; + + float x = evalX - halfKernelSize; + for (int i = 0; i < halfKernelSize; ++i, x += 1.f) { + if (x < -circleR || x > circleR) { + continue; } - for (int i = 0; i < halfKernelSize; ++i, x += 1.f) { - if (x < -circleR || x > circleR) { - continue; - } - float verticalEval = yKernelEvaluations[i + halfKernelSize]; - acc += verticalEval * halfKernel[i]; + float verticalEval = yKernelEvaluations[i]; + acc += verticalEval * halfKernel[halfKernelSize - i - 1]; + } + for (int i = 0; i < halfKernelSize; ++i, x += 1.f) { + if (x < -circleR || x > circleR) { + continue; } - - - return SkUnitScalarClampToByte(2.f * acc); + float verticalEval = yKernelEvaluations[i + halfKernelSize]; + acc += verticalEval * halfKernel[i]; } - - - - - - - - static uint8_t* create_circle_profile(float sigma, float circleR, int profileTextureWidth) { - const int numSteps = profileTextureWidth; - uint8_t* weights = new uint8_t[numSteps]; - - - int halfKernelSize = SkScalarCeilToInt(6.0f*sigma); - - halfKernelSize = ((halfKernelSize + 1) & ~1) >> 1; - - - int numYSteps = numSteps + 2 * halfKernelSize; - - SkAutoTArray<float> bulkAlloc(halfKernelSize + halfKernelSize + numYSteps); - float* halfKernel = bulkAlloc.get(); - float* summedKernel = bulkAlloc.get() + halfKernelSize; - float* yEvals = bulkAlloc.get() + 2 * halfKernelSize; - make_half_kernel_and_summed_table(halfKernel, summedKernel, halfKernelSize, sigma); - - float firstX = -halfKernelSize + 0.5f; - apply_kernel_in_y(yEvals, numYSteps, firstX, circleR, halfKernelSize, summedKernel); - - for (int i = 0; i < numSteps - 1; ++i) { - float evalX = i + 0.5f; - weights[i] = eval_at(evalX, circleR, halfKernel, halfKernelSize, yEvals + i); - } - - weights[numSteps - 1] = 0; - return weights; + return SkUnitScalarClampToByte(2.f * acc); +} + +static uint8_t* create_circle_profile(float sigma, float circleR, int profileTextureWidth) { + const int numSteps = profileTextureWidth; + uint8_t* weights = new uint8_t[numSteps]; + + int halfKernelSize = SkScalarCeilToInt(6.0f * sigma); + + halfKernelSize = ((halfKernelSize + 1) & ~1) >> 1; + + int numYSteps = numSteps + 2 * halfKernelSize; + + SkAutoTArray<float> bulkAlloc(halfKernelSize + halfKernelSize + numYSteps); + float* halfKernel = bulkAlloc.get(); + float* summedKernel = bulkAlloc.get() + halfKernelSize; + float* yEvals = bulkAlloc.get() + 2 * halfKernelSize; + make_half_kernel_and_summed_table(halfKernel, summedKernel, halfKernelSize, sigma); + + float firstX = -halfKernelSize + 0.5f; + apply_kernel_in_y(yEvals, numYSteps, firstX, circleR, halfKernelSize, summedKernel); + + for (int i = 0; i < numSteps - 1; ++i) { + float evalX = i + 0.5f; + weights[i] = eval_at(evalX, circleR, halfKernel, halfKernelSize, yEvals + i); } - static uint8_t* create_half_plane_profile(int profileWidth) { - SkASSERT(!(profileWidth & 0x1)); - - float sigma = profileWidth / 6.f; - int halfKernelSize = profileWidth / 2; - - SkAutoTArray<float> halfKernel(halfKernelSize); - uint8_t* profile = new uint8_t[profileWidth]; - - - const float tot = 2.f * make_unnormalized_half_kernel(halfKernel.get(), halfKernelSize, - sigma); - float sum = 0.f; - - for (int i = 0; i < halfKernelSize; ++i) { - halfKernel[halfKernelSize - i - 1] /= tot; - sum += halfKernel[halfKernelSize - i - 1]; - profile[profileWidth - i - 1] = SkUnitScalarClampToByte(sum); - } - - - for (int i = 0; i < halfKernelSize; ++i) { - sum += halfKernel[i]; - profile[halfKernelSize - i - 1] = SkUnitScalarClampToByte(sum); - } - - profile[profileWidth - 1] = 0; - return profile; + weights[numSteps - 1] = 0; + return weights; +} + +static uint8_t* create_half_plane_profile(int profileWidth) { + SkASSERT(!(profileWidth & 0x1)); + + float sigma = profileWidth / 6.f; + int halfKernelSize = profileWidth / 2; + + SkAutoTArray<float> halfKernel(halfKernelSize); + uint8_t* profile = new uint8_t[profileWidth]; + + const float tot = 2.f * make_unnormalized_half_kernel(halfKernel.get(), halfKernelSize, sigma); + float sum = 0.f; + + for (int i = 0; i < halfKernelSize; ++i) { + halfKernel[halfKernelSize - i - 1] /= tot; + sum += halfKernel[halfKernelSize - i - 1]; + profile[profileWidth - i - 1] = SkUnitScalarClampToByte(sum); + } + + for (int i = 0; i < halfKernelSize; ++i) { + sum += halfKernel[i]; + profile[halfKernelSize - i - 1] = SkUnitScalarClampToByte(sum); + } + + profile[profileWidth - 1] = 0; + return profile; +} + +static sk_sp<GrTextureProxy> create_profile_texture(GrResourceProvider* resourceProvider, + const SkRect& circle, float sigma, + float* solidRadius, float* textureRadius) { + float circleR = circle.width() / 2.0f; + + SkScalar sigmaToCircleRRatio = sigma / circleR; + + sigmaToCircleRRatio = SkTMin(sigmaToCircleRRatio, 8.f); + SkFixed sigmaToCircleRRatioFixed; + static const SkScalar kHalfPlaneThreshold = 0.1f; + bool useHalfPlaneApprox = false; + if (sigmaToCircleRRatio <= kHalfPlaneThreshold) { + useHalfPlaneApprox = true; + sigmaToCircleRRatioFixed = 0; + *solidRadius = circleR - 3 * sigma; + *textureRadius = 6 * sigma; + } else { + sigmaToCircleRRatioFixed = SkScalarToFixed(sigmaToCircleRRatio); + + sigmaToCircleRRatioFixed &= ~0xff; + sigmaToCircleRRatio = SkFixedToScalar(sigmaToCircleRRatioFixed); + sigma = circleR * sigmaToCircleRRatio; + *solidRadius = 0; + *textureRadius = circleR + 3 * sigma; } - static sk_sp<GrTextureProxy> create_profile_texture(GrResourceProvider* resourceProvider, - const SkRect& circle, - float sigma, - float* solidRadius, float* textureRadius) { - float circleR = circle.width() / 2.0f; - - - SkScalar sigmaToCircleRRatio = sigma / circleR; - - - - - sigmaToCircleRRatio = SkTMin(sigmaToCircleRRatio, 8.f); - SkFixed sigmaToCircleRRatioFixed; - static const SkScalar kHalfPlaneThreshold = 0.1f; - bool useHalfPlaneApprox = false; - if (sigmaToCircleRRatio <= kHalfPlaneThreshold) { - useHalfPlaneApprox = true; - sigmaToCircleRRatioFixed = 0; - *solidRadius = circleR - 3 * sigma; - *textureRadius = 6 * sigma; + static const GrUniqueKey::Domain kDomain = GrUniqueKey::GenerateDomain(); + GrUniqueKey key; + GrUniqueKey::Builder builder(&key, kDomain, 1); + builder[0] = sigmaToCircleRRatioFixed; + builder.finish(); + + sk_sp<GrTextureProxy> blurProfile = resourceProvider->findProxyByUniqueKey(key); + if (!blurProfile) { + static constexpr int kProfileTextureWidth = 512; + GrSurfaceDesc texDesc; + texDesc.fWidth = kProfileTextureWidth; + texDesc.fHeight = 1; + texDesc.fConfig = kAlpha_8_GrPixelConfig; + + std::unique_ptr<uint8_t[]> profile(nullptr); + if (useHalfPlaneApprox) { + profile.reset(create_half_plane_profile(kProfileTextureWidth)); } else { - - sigmaToCircleRRatioFixed = SkScalarToFixed(sigmaToCircleRRatio); - - - sigmaToCircleRRatioFixed &= ~0xff; - sigmaToCircleRRatio = SkFixedToScalar(sigmaToCircleRRatioFixed); - sigma = circleR * sigmaToCircleRRatio; - *solidRadius = 0; - *textureRadius = circleR + 3 * sigma; + SkScalar scale = kProfileTextureWidth / *textureRadius; + profile.reset( + create_circle_profile(sigma * scale, circleR * scale, kProfileTextureWidth)); } - static const GrUniqueKey::Domain kDomain = GrUniqueKey::GenerateDomain(); - GrUniqueKey key; - GrUniqueKey::Builder builder(&key, kDomain, 1); - builder[0] = sigmaToCircleRRatioFixed; - builder.finish(); - - sk_sp<GrTextureProxy> blurProfile = resourceProvider->findProxyByUniqueKey(key); + blurProfile = GrSurfaceProxy::MakeDeferred(resourceProvider, texDesc, SkBudgeted::kYes, + profile.get(), 0); if (!blurProfile) { - static constexpr int kProfileTextureWidth = 512; - GrSurfaceDesc texDesc; - texDesc.fWidth = kProfileTextureWidth; - texDesc.fHeight = 1; - texDesc.fConfig = kAlpha_8_GrPixelConfig; - - std::unique_ptr<uint8_t[]> profile(nullptr); - if (useHalfPlaneApprox) { - profile.reset(create_half_plane_profile(kProfileTextureWidth)); - } else { - - SkScalar scale = kProfileTextureWidth / *textureRadius; - profile.reset(create_circle_profile(sigma * scale, circleR * scale, - kProfileTextureWidth)); - } - - blurProfile = GrSurfaceProxy::MakeDeferred(resourceProvider, - texDesc, SkBudgeted::kYes, profile.get(), 0); - if (!blurProfile) { - return nullptr; - } - - resourceProvider->assignUniqueKeyToProxy(key, blurProfile.get()); + return nullptr; } - return blurProfile; + resourceProvider->assignUniqueKeyToProxy(key, blurProfile.get()); } - sk_sp<GrFragmentProcessor> GrCircleBlurFragmentProcessor::Make( - GrResourceProvider* resourceProvider, + return blurProfile; +} + +sk_sp<GrFragmentProcessor> GrCircleBlurFragmentProcessor::Make(GrResourceProvider* resourceProvider, const SkRect& circle, float sigma) { - float solidRadius; - float textureRadius; - sk_sp<GrTextureProxy> profile(create_profile_texture(resourceProvider, circle, sigma, - &solidRadius, &textureRadius)); - if (!profile) { - return nullptr; - } - return sk_sp<GrFragmentProcessor>(new GrCircleBlurFragmentProcessor(circle, - textureRadius, - solidRadius, - std::move(profile), - resourceProvider)); + float solidRadius; + float textureRadius; + sk_sp<GrTextureProxy> profile( + create_profile_texture(resourceProvider, circle, sigma, &solidRadius, &textureRadius)); + if (!profile) { + return nullptr; } + return sk_sp<GrFragmentProcessor>(new GrCircleBlurFragmentProcessor( + circle, textureRadius, solidRadius, std::move(profile), resourceProvider)); +} #include "glsl/GrGLSLColorSpaceXformHelper.h" #include "glsl/GrGLSLFragmentProcessor.h" #include "glsl/GrGLSLFragmentShaderBuilder.h" @@ -264,27 +227,43 @@ public: GrGLSLCircleBlurFragmentProcessor() {} void emitCode(EmitArgs& args) override { GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder; - const GrCircleBlurFragmentProcessor& _outer = args.fFp.cast<GrCircleBlurFragmentProcessor>(); - (void) _outer; - fCircleDataVar = args.fUniformHandler->addUniform(kFragment_GrShaderFlag, kVec4f_GrSLType, kDefault_GrSLPrecision, "circleData"); - fragBuilder->codeAppendf("vec2 vec = vec2((sk_FragCoord.x - %s.x) * %s.w, (sk_FragCoord.y - %s.y) * %s.w);\nfloat dist = length(vec) + (0.5 - %s.z) * %s.w;\n%s = %s * texture(%s, vec2(dist, 0.5)).%s.w;\n", args.fUniformHandler->getUniformCStr(fCircleDataVar), args.fUniformHandler->getUniformCStr(fCircleDataVar), args.fUniformHandler->getUniformCStr(fCircleDataVar), args.fUniformHandler->getUniformCStr(fCircleDataVar), args.fUniformHandler->getUniformCStr(fCircleDataVar), args.fUniformHandler->getUniformCStr(fCircleDataVar), args.fOutputColor, args.fInputColor ? args.fInputColor : "vec4(1)", fragBuilder->getProgramBuilder()->samplerVariable(args.fTexSamplers[0]).c_str(), fragBuilder->getProgramBuilder()->samplerSwizzle(args.fTexSamplers[0]).c_str()); + const GrCircleBlurFragmentProcessor& _outer = + args.fFp.cast<GrCircleBlurFragmentProcessor>(); + (void)_outer; + fCircleDataVar = args.fUniformHandler->addUniform(kFragment_GrShaderFlag, kVec4f_GrSLType, + kDefault_GrSLPrecision, "circleData"); + fragBuilder->codeAppendf( + "vec2 vec = vec2((sk_FragCoord.x - %s.x) * %s.w, (sk_FragCoord.y - %s.y) * " + "%s.w);\nfloat dist = length(vec) + (0.5 - %s.z) * %s.w;\n%s = %s * texture(%s, " + "vec2(dist, 0.5)).%s.w;\n", + args.fUniformHandler->getUniformCStr(fCircleDataVar), + args.fUniformHandler->getUniformCStr(fCircleDataVar), + args.fUniformHandler->getUniformCStr(fCircleDataVar), + args.fUniformHandler->getUniformCStr(fCircleDataVar), + args.fUniformHandler->getUniformCStr(fCircleDataVar), + args.fUniformHandler->getUniformCStr(fCircleDataVar), args.fOutputColor, + args.fInputColor ? args.fInputColor : "vec4(1)", + fragBuilder->getProgramBuilder()->samplerVariable(args.fTexSamplers[0]).c_str(), + fragBuilder->getProgramBuilder()->samplerSwizzle(args.fTexSamplers[0]).c_str()); } + private: - void onSetData(const GrGLSLProgramDataManager& data, const GrFragmentProcessor& _proc) override { + void onSetData(const GrGLSLProgramDataManager& data, + const GrFragmentProcessor& _proc) override { const GrCircleBlurFragmentProcessor& _outer = _proc.cast<GrCircleBlurFragmentProcessor>(); auto circleRect = _outer.circleRect(); - (void) circleRect; + (void)circleRect; auto textureRadius = _outer.textureRadius(); - (void) textureRadius; + (void)textureRadius; auto solidRadius = _outer.solidRadius(); - (void) solidRadius; + (void)solidRadius; UniformHandle& blurProfileSampler = fBlurProfileSamplerVar; - (void) blurProfileSampler; + (void)blurProfileSampler; UniformHandle& circleData = fCircleDataVar; - (void) circleData; + (void)circleData; - data.set4f(circleData, circleRect.centerX(), circleRect.centerY(), solidRadius, - 1.f / textureRadius); + data.set4f(circleData, circleRect.centerX(), circleRect.centerY(), solidRadius, + 1.f / textureRadius); } UniformHandle fCircleDataVar; UniformHandle fBlurProfileSamplerVar; @@ -292,11 +271,11 @@ private: GrGLSLFragmentProcessor* GrCircleBlurFragmentProcessor::onCreateGLSLInstance() const { return new GrGLSLCircleBlurFragmentProcessor(); } -void GrCircleBlurFragmentProcessor::onGetGLSLProcessorKey(const GrShaderCaps& caps, GrProcessorKeyBuilder* b) const { -} +void GrCircleBlurFragmentProcessor::onGetGLSLProcessorKey(const GrShaderCaps& caps, + GrProcessorKeyBuilder* b) const {} bool GrCircleBlurFragmentProcessor::onIsEqual(const GrFragmentProcessor& other) const { const GrCircleBlurFragmentProcessor& that = other.cast<GrCircleBlurFragmentProcessor>(); - (void) that; + (void)that; if (fCircleRect != that.fCircleRect) return false; if (fTextureRadius != that.fTextureRadius) return false; if (fSolidRadius != that.fSolidRadius) return false; @@ -305,10 +284,10 @@ bool GrCircleBlurFragmentProcessor::onIsEqual(const GrFragmentProcessor& other) } GR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrCircleBlurFragmentProcessor); #if GR_TEST_UTILS -sk_sp<GrFragmentProcessor> GrCircleBlurFragmentProcessor::TestCreate(GrProcessorTestData* testData) { - +sk_sp<GrFragmentProcessor> GrCircleBlurFragmentProcessor::TestCreate( + GrProcessorTestData* testData) { SkScalar wh = testData->fRandom->nextRangeScalar(100.f, 1000.f); - SkScalar sigma = testData->fRandom->nextRangeF(1.f,10.f); + SkScalar sigma = testData->fRandom->nextRangeF(1.f, 10.f); SkRect circle = SkRect::MakeWH(wh, wh); return GrCircleBlurFragmentProcessor::Make(testData->resourceProvider(), circle, sigma); } diff --git a/src/effects/GrCircleBlurFragmentProcessor.h b/src/effects/GrCircleBlurFragmentProcessor.h index 72632d2796..354928d49e 100644 --- a/src/effects/GrCircleBlurFragmentProcessor.h +++ b/src/effects/GrCircleBlurFragmentProcessor.h @@ -25,22 +25,21 @@ public: static sk_sp<GrFragmentProcessor> Make(GrResourceProvider* resourceProvider, const SkRect& circle, float sigma); const char* name() const override { return "CircleBlurFragmentProcessor"; } + private: - GrCircleBlurFragmentProcessor(SkRect circleRect, float textureRadius, float solidRadius, sk_sp<GrTextureProxy> blurProfileSampler, - GrResourceProvider* resourceProvider -) - : INHERITED((OptimizationFlags) - kCompatibleWithCoverageAsAlpha_OptimizationFlag -) - , fCircleRect(circleRect) - , fTextureRadius(textureRadius) - , fSolidRadius(solidRadius) - , fBlurProfileSampler(std::move(blurProfileSampler)) { + GrCircleBlurFragmentProcessor(SkRect circleRect, float textureRadius, float solidRadius, + sk_sp<GrTextureProxy> blurProfileSampler, + GrResourceProvider* resourceProvider) + : INHERITED((OptimizationFlags)kCompatibleWithCoverageAsAlpha_OptimizationFlag) + , fCircleRect(circleRect) + , fTextureRadius(textureRadius) + , fSolidRadius(solidRadius) + , fBlurProfileSampler(std::move(blurProfileSampler)) { this->addTextureSampler(&fBlurProfileSampler); this->initClassID<GrCircleBlurFragmentProcessor>(); } GrGLSLFragmentProcessor* onCreateGLSLInstance() const override; - void onGetGLSLProcessorKey(const GrShaderCaps&,GrProcessorKeyBuilder*) const override; + void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override; bool onIsEqual(const GrFragmentProcessor&) const override; GR_DECLARE_FRAGMENT_PROCESSOR_TEST SkRect fCircleRect; |