diff options
author | 2017-04-05 10:09:00 -0400 | |
---|---|---|
committer | 2017-04-05 17:20:38 +0000 | |
commit | ee805329bfd5cea669d4af20a554e4b213dbf011 (patch) | |
tree | 98a32b0eff7caf39393914bc8bab7f0c458ae1dd /src | |
parent | aaee31f18c0845417103d84285e365575def3c40 (diff) |
Remove texture sampling from GrConfigConversionEffect
Elevates default precision for the entire fragment program
to maintain precision on some ES implementations.
Re-land fixed version of:
https://skia-review.googlesource.com/10026/
https://skia-review.googlesource.com/10056
BUG=skia:
Change-Id: Ibe43dba9c223e430b2f9f8ed5cb97ed7a049e6c2
Reviewed-on: https://skia-review.googlesource.com/10160
Reviewed-by: Brian Salomon <bsalomon@google.com>
Commit-Queue: Brian Osman <brianosman@google.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/gpu/GrContext.cpp | 34 | ||||
-rw-r--r-- | src/gpu/effects/GrConfigConversionEffect.cpp | 103 | ||||
-rw-r--r-- | src/gpu/effects/GrConfigConversionEffect.h | 18 |
3 files changed, 62 insertions, 93 deletions
diff --git a/src/gpu/GrContext.cpp b/src/gpu/GrContext.cpp index c1961f9557..df5c16df4a 100644 --- a/src/gpu/GrContext.cpp +++ b/src/gpu/GrContext.cpp @@ -909,20 +909,19 @@ sk_sp<GrFragmentProcessor> GrContext::createPMToUPMEffect(sk_sp<GrTextureProxy> ASSERT_SINGLE_OWNER // We should have already called this->testPMConversionsIfNecessary(). SkASSERT(fDidTestPMConversions); - if (kRGBA_half_GrPixelConfig == proxy->config()) { - return GrFragmentProcessor::UnpremulOutput( - GrSimpleTextureEffect::Make(this->resourceProvider(), std::move(proxy), - nullptr, matrix)); - } else { + GrPixelConfig config = proxy->config(); + sk_sp<GrFragmentProcessor> fp = GrSimpleTextureEffect::Make(this->resourceProvider(), + std::move(proxy), nullptr, matrix); + if (kRGBA_half_GrPixelConfig == config) { + return GrFragmentProcessor::UnpremulOutput(std::move(fp)); + } else if (kRGBA_8888_GrPixelConfig == config || kBGRA_8888_GrPixelConfig == config) { GrConfigConversionEffect::PMConversion pmToUPM = static_cast<GrConfigConversionEffect::PMConversion>(fPMToUPMConversion); if (GrConfigConversionEffect::kPMConversionCnt != pmToUPM) { - return GrConfigConversionEffect::Make(this->resourceProvider(), std::move(proxy), - pmToUPM, matrix); - } else { - return nullptr; + return GrConfigConversionEffect::Make(std::move(fp), pmToUPM); } } + return nullptr; } sk_sp<GrFragmentProcessor> GrContext::createUPMToPMEffect(sk_sp<GrTextureProxy> proxy, @@ -930,20 +929,19 @@ sk_sp<GrFragmentProcessor> GrContext::createUPMToPMEffect(sk_sp<GrTextureProxy> ASSERT_SINGLE_OWNER // We should have already called this->testPMConversionsIfNecessary(). SkASSERT(fDidTestPMConversions); - if (kRGBA_half_GrPixelConfig == proxy->config()) { - return GrFragmentProcessor::PremulOutput( - GrSimpleTextureEffect::Make(this->resourceProvider(), std::move(proxy), - nullptr, matrix)); - } else { + GrPixelConfig config = proxy->config(); + sk_sp<GrFragmentProcessor> fp = GrSimpleTextureEffect::Make(this->resourceProvider(), + std::move(proxy), nullptr, matrix); + if (kRGBA_half_GrPixelConfig == config) { + return GrFragmentProcessor::PremulOutput(std::move(fp)); + } else if (kRGBA_8888_GrPixelConfig == config || kBGRA_8888_GrPixelConfig == config) { GrConfigConversionEffect::PMConversion upmToPM = static_cast<GrConfigConversionEffect::PMConversion>(fUPMToPMConversion); if (GrConfigConversionEffect::kPMConversionCnt != upmToPM) { - return GrConfigConversionEffect::Make(this->resourceProvider(), std::move(proxy), - upmToPM, matrix); - } else { - return nullptr; + return GrConfigConversionEffect::Make(std::move(fp), upmToPM); } } + return nullptr; } bool GrContext::validPMUPMConversionExists(GrPixelConfig config) const { diff --git a/src/gpu/effects/GrConfigConversionEffect.cpp b/src/gpu/effects/GrConfigConversionEffect.cpp index ac4d30016a..07225f1fc6 100644 --- a/src/gpu/effects/GrConfigConversionEffect.cpp +++ b/src/gpu/effects/GrConfigConversionEffect.cpp @@ -10,7 +10,6 @@ #include "GrClip.h" #include "GrContext.h" #include "GrRenderTargetContext.h" -#include "GrSimpleTextureEffect.h" #include "SkMatrix.h" #include "glsl/GrGLSLFragmentProcessor.h" #include "glsl/GrGLSLFragmentShaderBuilder.h" @@ -19,59 +18,43 @@ class GrGLConfigConversionEffect : public GrGLSLFragmentProcessor { public: void emitCode(EmitArgs& args) override { const GrConfigConversionEffect& cce = args.fFp.cast<GrConfigConversionEffect>(); - GrConfigConversionEffect::PMConversion pmConversion = cce.pmConversion(); - - // Using highp for GLES here in order to avoid some precision issues on specific GPUs. - GrShaderVar tmpVar("tmpColor", kVec4f_GrSLType, 0, kHigh_GrSLPrecision); - SkString tmpDecl; - tmpVar.appendDecl(args.fShaderCaps, &tmpDecl); - GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder; - fragBuilder->codeAppendf("%s;", tmpDecl.c_str()); + // Use highp throughout the shader to avoid some precision issues on specific GPUs. + fragBuilder->elevateDefaultPrecision(kHigh_GrSLPrecision); - fragBuilder->codeAppendf("%s = ", tmpVar.c_str()); - fragBuilder->appendTextureLookup(args.fTexSamplers[0], args.fTransformedCoords[0].c_str(), - args.fTransformedCoords[0].getType()); - fragBuilder->codeAppend(";"); + if (nullptr == args.fInputColor) { + // could optimize this case, but we aren't for now. + args.fInputColor = "vec4(1)"; + } + fragBuilder->codeAppendf("vec4 color = %s;", args.fInputColor); - switch (pmConversion) { + switch (cce.pmConversion()) { case GrConfigConversionEffect::kMulByAlpha_RoundUp_PMConversion: - fragBuilder->codeAppendf( - "%s = vec4(ceil(%s.rgb * %s.a * 255.0) / 255.0, %s.a);", - tmpVar.c_str(), tmpVar.c_str(), tmpVar.c_str(), tmpVar.c_str()); + fragBuilder->codeAppend( + "color.rgb = ceil(color.rgb * color.a * 255.0) / 255.0;"); break; case GrConfigConversionEffect::kMulByAlpha_RoundDown_PMConversion: // Add a compensation(0.001) here to avoid the side effect of the floor operation. // In Intel GPUs, the integer value converted from floor(%s.r * 255.0) / 255.0 // is less than the integer value converted from %s.r by 1 when the %s.r is // converted from the integer value 2^n, such as 1, 2, 4, 8, etc. - fragBuilder->codeAppendf( - "%s = vec4(floor(%s.rgb * %s.a * 255.0 + 0.001) / 255.0, %s.a);", - tmpVar.c_str(), tmpVar.c_str(), tmpVar.c_str(), tmpVar.c_str()); - + fragBuilder->codeAppend( + "color.rgb = floor(color.rgb * color.a * 255.0 + 0.001) / 255.0;"); break; case GrConfigConversionEffect::kDivByAlpha_RoundUp_PMConversion: - fragBuilder->codeAppendf( - "%s = %s.a <= 0.0 ? vec4(0,0,0,0) : vec4(ceil(%s.rgb / %s.a * 255.0) / 255.0, %s.a);", - tmpVar.c_str(), tmpVar.c_str(), tmpVar.c_str(), tmpVar.c_str(), - tmpVar.c_str()); + fragBuilder->codeAppend( + "color.rgb = color.a <= 0.0 ? vec3(0,0,0) : ceil(color.rgb / color.a * 255.0) / 255.0;"); break; case GrConfigConversionEffect::kDivByAlpha_RoundDown_PMConversion: - fragBuilder->codeAppendf( - "%s = %s.a <= 0.0 ? vec4(0,0,0,0) : vec4(floor(%s.rgb / %s.a * 255.0) / 255.0, %s.a);", - tmpVar.c_str(), tmpVar.c_str(), tmpVar.c_str(), tmpVar.c_str(), - tmpVar.c_str()); + fragBuilder->codeAppend( + "color.rgb = color.a <= 0.0 ? vec3(0,0,0) : floor(color.rgb / color.a * 255.0) / 255.0;"); break; default: SkFAIL("Unknown conversion op."); break; } - fragBuilder->codeAppendf("%s = %s;", args.fOutputColor, tmpVar.c_str()); - - SkString modulate; - GrGLSLMulVarBy4f(&modulate, args.fOutputColor, args.fInputColor); - fragBuilder->codeAppend(modulate.c_str()); + fragBuilder->codeAppendf("%s = color;", args.fOutputColor); } static inline void GenKey(const GrProcessor& processor, const GrShaderCaps&, @@ -87,17 +70,11 @@ private: }; /////////////////////////////////////////////////////////////////////////////// -GrConfigConversionEffect::GrConfigConversionEffect(GrResourceProvider* resourceProvider, - sk_sp<GrTextureProxy> proxy, - PMConversion pmConversion, - const SkMatrix& matrix) - : INHERITED(resourceProvider, kNone_OptimizationFlags, proxy, nullptr, matrix) + +GrConfigConversionEffect::GrConfigConversionEffect(PMConversion pmConversion) + : INHERITED(kNone_OptimizationFlags) , fPMConversion(pmConversion) { this->initClassID<GrConfigConversionEffect>(); - // We expect to get here with non-BGRA/RGBA only if we're doing not doing a premul/unpremul - // conversion. - SkASSERT(kRGBA_8888_GrPixelConfig == proxy->config() || - kBGRA_8888_GrPixelConfig == proxy->config()); } bool GrConfigConversionEffect::onIsEqual(const GrFragmentProcessor& s) const { @@ -112,10 +89,7 @@ GR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrConfigConversionEffect); #if GR_TEST_UTILS sk_sp<GrFragmentProcessor> GrConfigConversionEffect::TestCreate(GrProcessorTestData* d) { PMConversion pmConv = static_cast<PMConversion>(d->fRandom->nextULessThan(kPMConversionCnt)); - return sk_sp<GrFragmentProcessor>(new GrConfigConversionEffect( - d->resourceProvider(), - d->textureProxy(GrProcessorUnitTest::kSkiaPMTextureIdx), - pmConv, GrTest::TestMatrix(d->fRandom))); + return sk_sp<GrFragmentProcessor>(new GrConfigConversionEffect(pmConv)); } #endif @@ -203,14 +177,11 @@ void GrConfigConversionEffect::TestForPreservingPMConversions(GrContext* context GrPaint paint1; GrPaint paint2; GrPaint paint3; - sk_sp<GrFragmentProcessor> pmToUPM1(new GrConfigConversionEffect( - resourceProvider, dataProxy, *pmToUPMRule, SkMatrix::I())); - sk_sp<GrFragmentProcessor> upmToPM(new GrConfigConversionEffect( - resourceProvider, readRTC->asTextureProxyRef(), *upmToPMRule, SkMatrix::I())); - sk_sp<GrFragmentProcessor> pmToUPM2(new GrConfigConversionEffect( - resourceProvider, tempRTC->asTextureProxyRef(), *pmToUPMRule, SkMatrix::I())); - - paint1.addColorFragmentProcessor(std::move(pmToUPM1)); + sk_sp<GrFragmentProcessor> pmToUPM(new GrConfigConversionEffect(*pmToUPMRule)); + sk_sp<GrFragmentProcessor> upmToPM(new GrConfigConversionEffect(*upmToPMRule)); + + paint1.addColorTextureProcessor(resourceProvider, dataProxy, nullptr, SkMatrix::I()); + paint1.addColorFragmentProcessor(pmToUPM); paint1.setPorterDuffXPFactory(SkBlendMode::kSrc); readRTC->fillRectToRect(GrNoClip(), std::move(paint1), GrAA::kNo, SkMatrix::I(), kDstRect, @@ -220,13 +191,17 @@ void GrConfigConversionEffect::TestForPreservingPMConversions(GrContext* context continue; } + paint2.addColorTextureProcessor(resourceProvider, readRTC->asTextureProxyRef(), nullptr, + SkMatrix::I()); paint2.addColorFragmentProcessor(std::move(upmToPM)); paint2.setPorterDuffXPFactory(SkBlendMode::kSrc); tempRTC->fillRectToRect(GrNoClip(), std::move(paint2), GrAA::kNo, SkMatrix::I(), kDstRect, kSrcRect); - paint3.addColorFragmentProcessor(std::move(pmToUPM2)); + paint3.addColorTextureProcessor(resourceProvider, tempRTC->asTextureProxyRef(), nullptr, + SkMatrix::I()); + paint3.addColorFragmentProcessor(std::move(pmToUPM)); paint3.setPorterDuffXPFactory(SkBlendMode::kSrc); readRTC->fillRectToRect(GrNoClip(), std::move(paint3), GrAA::kNo, SkMatrix::I(), kDstRect, @@ -252,16 +227,12 @@ void GrConfigConversionEffect::TestForPreservingPMConversions(GrContext* context } } -sk_sp<GrFragmentProcessor> GrConfigConversionEffect::Make(GrResourceProvider* resourceProvider, - sk_sp<GrTextureProxy> proxy, - PMConversion pmConversion, - const SkMatrix& matrix) { - if (kRGBA_8888_GrPixelConfig != proxy->config() && - kBGRA_8888_GrPixelConfig != proxy->config()) { - // The PM conversions assume colors are 0..255 +sk_sp<GrFragmentProcessor> GrConfigConversionEffect::Make(sk_sp<GrFragmentProcessor> fp, + PMConversion pmConversion) { + if (!fp) { return nullptr; } - return sk_sp<GrFragmentProcessor>(new GrConfigConversionEffect(resourceProvider, - std::move(proxy), - pmConversion, matrix)); + sk_sp<GrFragmentProcessor> ccFP(new GrConfigConversionEffect(pmConversion)); + sk_sp<GrFragmentProcessor> fpPipeline[] = { fp, ccFP }; + return GrFragmentProcessor::RunInSeries(fpPipeline, 2); } diff --git a/src/gpu/effects/GrConfigConversionEffect.h b/src/gpu/effects/GrConfigConversionEffect.h index d3e40ddd00..e5fa10cd9b 100644 --- a/src/gpu/effects/GrConfigConversionEffect.h +++ b/src/gpu/effects/GrConfigConversionEffect.h @@ -8,15 +8,13 @@ #ifndef GrConfigConversionEffect_DEFINED #define GrConfigConversionEffect_DEFINED -#include "GrSingleTextureEffect.h" - -class GrInvariantOutput; +#include "GrFragmentProcessor.h" /** * This class is used to perform config conversions. Clients may want to read/write data that is * unpremultiplied. */ -class GrConfigConversionEffect : public GrSingleTextureEffect { +class GrConfigConversionEffect : public GrFragmentProcessor { public: /** * The PM->UPM or UPM->PM conversions to apply. @@ -30,8 +28,11 @@ public: kPMConversionCnt }; - static sk_sp<GrFragmentProcessor> Make(GrResourceProvider*, sk_sp<GrTextureProxy>, - PMConversion, const SkMatrix&); + /** + * Returns a fragment processor that calls the passed in fragment processor, and then performs + * the requested premul or unpremul conversion. + */ + static sk_sp<GrFragmentProcessor> Make(sk_sp<GrFragmentProcessor>, PMConversion); const char* name() const override { return "Config Conversion"; } @@ -46,8 +47,7 @@ public: PMConversion* PMToUPMRule, PMConversion* UPMToPMRule); private: - GrConfigConversionEffect(GrResourceProvider*, sk_sp<GrTextureProxy>, - PMConversion, const SkMatrix& matrix); + GrConfigConversionEffect(PMConversion); GrGLSLFragmentProcessor* onCreateGLSLInstance() const override; @@ -59,7 +59,7 @@ private: GR_DECLARE_FRAGMENT_PROCESSOR_TEST; - typedef GrSingleTextureEffect INHERITED; + typedef GrFragmentProcessor INHERITED; }; #endif |