aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorGravatar Brian Osman <brianosman@google.com>2017-04-05 10:09:00 -0400
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2017-04-05 17:20:38 +0000
commitee805329bfd5cea669d4af20a554e4b213dbf011 (patch)
tree98a32b0eff7caf39393914bc8bab7f0c458ae1dd /src
parentaaee31f18c0845417103d84285e365575def3c40 (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.cpp34
-rw-r--r--src/gpu/effects/GrConfigConversionEffect.cpp103
-rw-r--r--src/gpu/effects/GrConfigConversionEffect.h18
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