| Index: src/gpu/effects/GrConfigConversionEffect.cpp
|
| diff --git a/src/gpu/effects/GrConfigConversionEffect.cpp b/src/gpu/effects/GrConfigConversionEffect.cpp
|
| index 129d057b7f146b018cf1503b62f701d1bdebe049..5ac86a96756eba7266fbe44ada8a20bc18dfbe8a 100644
|
| --- a/src/gpu/effects/GrConfigConversionEffect.cpp
|
| +++ b/src/gpu/effects/GrConfigConversionEffect.cpp
|
| @@ -16,14 +16,13 @@
|
|
|
| class GrGLConfigConversionEffect : public GrGLSLFragmentProcessor {
|
| public:
|
| - GrGLConfigConversionEffect(const GrProcessor& processor) {
|
| - const GrConfigConversionEffect& configConversionEffect =
|
| - processor.cast<GrConfigConversionEffect>();
|
| - fSwapRedAndBlue = configConversionEffect.swapsRedAndBlue();
|
| - fPMConversion = configConversionEffect.pmConversion();
|
| - }
|
| + GrGLConfigConversionEffect() {}
|
|
|
| virtual void emitCode(EmitArgs& args) override {
|
| + const GrConfigConversionEffect& cce = args.fFp.cast<GrConfigConversionEffect>();
|
| + const GrSwizzle& swizzle = cce.swizzle();
|
| + GrConfigConversionEffect::PMConversion pmConversion = cce.pmConversion();
|
| +
|
| // Using highp for GLES here in order to avoid some precision issues on specific GPUs.
|
| GrGLSLShaderVar tmpVar("tmpColor", kVec4f_GrSLType, 0, kHigh_GrSLPrecision);
|
| SkString tmpDecl;
|
| @@ -38,16 +37,16 @@ public:
|
| args.fCoords[0].getType());
|
| fragBuilder->codeAppend(";");
|
|
|
| - if (GrConfigConversionEffect::kNone_PMConversion == fPMConversion) {
|
| - SkASSERT(fSwapRedAndBlue);
|
| - fragBuilder->codeAppendf("%s = %s.bgra;", args.fOutputColor, tmpVar.c_str());
|
| + if (GrConfigConversionEffect::kNone_PMConversion == pmConversion) {
|
| + SkASSERT(GrSwizzle::RGBA() != swizzle);
|
| + fragBuilder->codeAppendf("%s = %s.%s;", args.fOutputColor, tmpVar.c_str(),
|
| + swizzle.c_str());
|
| } else {
|
| - const char* swiz = fSwapRedAndBlue ? "bgr" : "rgb";
|
| - switch (fPMConversion) {
|
| + switch (pmConversion) {
|
| case GrConfigConversionEffect::kMulByAlpha_RoundUp_PMConversion:
|
| fragBuilder->codeAppendf(
|
| - "%s = vec4(ceil(%s.%s * %s.a * 255.0) / 255.0, %s.a);",
|
| - tmpVar.c_str(), tmpVar.c_str(), swiz, tmpVar.c_str(), tmpVar.c_str());
|
| + "%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());
|
| break;
|
| case GrConfigConversionEffect::kMulByAlpha_RoundDown_PMConversion:
|
| // Add a compensation(0.001) here to avoid the side effect of the floor operation.
|
| @@ -55,24 +54,28 @@ public:
|
| // 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.%s * %s.a * 255.0 + 0.001) / 255.0, %s.a);",
|
| - tmpVar.c_str(), tmpVar.c_str(), swiz, tmpVar.c_str(), tmpVar.c_str());
|
| + "%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());
|
| +
|
| break;
|
| case GrConfigConversionEffect::kDivByAlpha_RoundUp_PMConversion:
|
| fragBuilder->codeAppendf(
|
| - "%s = %s.a <= 0.0 ? vec4(0,0,0,0) : vec4(ceil(%s.%s / %s.a * 255.0) / 255.0, %s.a);",
|
| - tmpVar.c_str(), tmpVar.c_str(), tmpVar.c_str(), swiz, tmpVar.c_str(), tmpVar.c_str());
|
| + "%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());
|
| break;
|
| case GrConfigConversionEffect::kDivByAlpha_RoundDown_PMConversion:
|
| fragBuilder->codeAppendf(
|
| - "%s = %s.a <= 0.0 ? vec4(0,0,0,0) : vec4(floor(%s.%s / %s.a * 255.0) / 255.0, %s.a);",
|
| - tmpVar.c_str(), tmpVar.c_str(), tmpVar.c_str(), swiz, tmpVar.c_str(), tmpVar.c_str());
|
| + "%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());
|
| break;
|
| default:
|
| SkFAIL("Unknown conversion op.");
|
| break;
|
| }
|
| - fragBuilder->codeAppendf("%s = %s;", args.fOutputColor, tmpVar.c_str());
|
| + fragBuilder->codeAppendf("%s = %s.%s;", args.fOutputColor, tmpVar.c_str(),
|
| + swizzle.c_str());
|
| }
|
| SkString modulate;
|
| GrGLSLMulVarBy4f(&modulate, args.fOutputColor, args.fInputColor);
|
| @@ -81,15 +84,12 @@ public:
|
|
|
| static inline void GenKey(const GrProcessor& processor, const GrGLSLCaps&,
|
| GrProcessorKeyBuilder* b) {
|
| - const GrConfigConversionEffect& conv = processor.cast<GrConfigConversionEffect>();
|
| - uint32_t key = (conv.swapsRedAndBlue() ? 0 : 1) | (conv.pmConversion() << 1);
|
| + const GrConfigConversionEffect& cce = processor.cast<GrConfigConversionEffect>();
|
| + uint32_t key = (cce.swizzle().asKey()) | (cce.pmConversion() << 16);
|
| b->add32(key);
|
| }
|
|
|
| private:
|
| - bool fSwapRedAndBlue;
|
| - GrConfigConversionEffect::PMConversion fPMConversion;
|
| -
|
| typedef GrGLSLFragmentProcessor INHERITED;
|
|
|
| };
|
| @@ -97,11 +97,11 @@ private:
|
| ///////////////////////////////////////////////////////////////////////////////
|
|
|
| GrConfigConversionEffect::GrConfigConversionEffect(GrTexture* texture,
|
| - bool swapRedAndBlue,
|
| + const GrSwizzle& swizzle,
|
| PMConversion pmConversion,
|
| const SkMatrix& matrix)
|
| : INHERITED(texture, matrix)
|
| - , fSwapRedAndBlue(swapRedAndBlue)
|
| + , fSwizzle(swizzle)
|
| , fPMConversion(pmConversion) {
|
| this->initClassID<GrConfigConversionEffect>();
|
| // We expect to get here with non-BGRA/RGBA only if we're doing not doing a premul/unpremul
|
| @@ -110,12 +110,12 @@ GrConfigConversionEffect::GrConfigConversionEffect(GrTexture* texture,
|
| kBGRA_8888_GrPixelConfig == texture->config()) ||
|
| kNone_PMConversion == pmConversion);
|
| // Why did we pollute our texture cache instead of using a GrSingleTextureEffect?
|
| - SkASSERT(swapRedAndBlue || kNone_PMConversion != pmConversion);
|
| + SkASSERT(swizzle != GrSwizzle::RGBA() || kNone_PMConversion != pmConversion);
|
| }
|
|
|
| bool GrConfigConversionEffect::onIsEqual(const GrFragmentProcessor& s) const {
|
| const GrConfigConversionEffect& other = s.cast<GrConfigConversionEffect>();
|
| - return other.fSwapRedAndBlue == fSwapRedAndBlue &&
|
| + return other.fSwizzle == fSwizzle &&
|
| other.fPMConversion == fPMConversion;
|
| }
|
|
|
| @@ -129,14 +129,12 @@ GR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrConfigConversionEffect);
|
|
|
| const GrFragmentProcessor* GrConfigConversionEffect::TestCreate(GrProcessorTestData* d) {
|
| PMConversion pmConv = static_cast<PMConversion>(d->fRandom->nextULessThan(kPMConversionCnt));
|
| - bool swapRB;
|
| - if (kNone_PMConversion == pmConv) {
|
| - swapRB = true;
|
| - } else {
|
| - swapRB = d->fRandom->nextBool();
|
| - }
|
| + GrSwizzle swizzle;
|
| + do {
|
| + swizzle = GrSwizzle::CreateRandom(d->fRandom);
|
| + } while (pmConv == kNone_PMConversion && swizzle == GrSwizzle::RGBA());
|
| return new GrConfigConversionEffect(d->fTextures[GrProcessorUnitTest::kSkiaPMTextureIdx],
|
| - swapRB, pmConv, GrTest::TestMatrix(d->fRandom));
|
| + swizzle, pmConv, GrTest::TestMatrix(d->fRandom));
|
| }
|
|
|
| ///////////////////////////////////////////////////////////////////////////////
|
| @@ -147,7 +145,7 @@ void GrConfigConversionEffect::onGetGLSLProcessorKey(const GrGLSLCaps& caps,
|
| }
|
|
|
| GrGLSLFragmentProcessor* GrConfigConversionEffect::onCreateGLSLInstance() const {
|
| - return new GrGLConfigConversionEffect(*this);
|
| + return new GrGLConfigConversionEffect();
|
| }
|
|
|
|
|
| @@ -215,11 +213,11 @@ void GrConfigConversionEffect::TestForPreservingPMConversions(GrContext* context
|
| GrPaint paint2;
|
| GrPaint paint3;
|
| SkAutoTUnref<GrFragmentProcessor> pmToUPM1(new GrConfigConversionEffect(
|
| - dataTex, false, *pmToUPMRule, SkMatrix::I()));
|
| + dataTex, GrSwizzle::RGBA(), *pmToUPMRule, SkMatrix::I()));
|
| SkAutoTUnref<GrFragmentProcessor> upmToPM(new GrConfigConversionEffect(
|
| - readTex, false, *upmToPMRule, SkMatrix::I()));
|
| + readTex, GrSwizzle::RGBA(), *upmToPMRule, SkMatrix::I()));
|
| SkAutoTUnref<GrFragmentProcessor> pmToUPM2(new GrConfigConversionEffect(
|
| - tempTex, false, *pmToUPMRule, SkMatrix::I()));
|
| + tempTex, GrSwizzle::RGBA(), *pmToUPMRule, SkMatrix::I()));
|
|
|
| paint1.addColorFragmentProcessor(pmToUPM1);
|
| paint1.setPorterDuffXPFactory(SkXfermode::kSrc_Mode);
|
| @@ -289,10 +287,10 @@ void GrConfigConversionEffect::TestForPreservingPMConversions(GrContext* context
|
| }
|
|
|
| const GrFragmentProcessor* GrConfigConversionEffect::Create(GrTexture* texture,
|
| - bool swapRedAndBlue,
|
| + const GrSwizzle& swizzle,
|
| PMConversion pmConversion,
|
| const SkMatrix& matrix) {
|
| - if (!swapRedAndBlue && kNone_PMConversion == pmConversion) {
|
| + if (swizzle == GrSwizzle::RGBA() && kNone_PMConversion == pmConversion) {
|
| // If we returned a GrConfigConversionEffect that was equivalent to a GrSimpleTextureEffect
|
| // then we may pollute our texture cache with redundant shaders. So in the case that no
|
| // conversions were requested we instead return a GrSimpleTextureEffect.
|
| @@ -304,6 +302,6 @@ const GrFragmentProcessor* GrConfigConversionEffect::Create(GrTexture* texture,
|
| // The PM conversions assume colors are 0..255
|
| return nullptr;
|
| }
|
| - return new GrConfigConversionEffect(texture, swapRedAndBlue, pmConversion, matrix);
|
| + return new GrConfigConversionEffect(texture, swizzle, pmConversion, matrix);
|
| }
|
| }
|
|
|