return true;
}
+static bool valid_unpremul_config(GrPixelConfig config) {
+ return GrPixelConfigIs8888Unorm(config) || kRGBA_half_GrPixelConfig == config;
+}
+
bool GrContext::writeSurfacePixels(GrSurface* surface, SkColorSpace* dstColorSpace,
int left, int top, int width, int height,
GrPixelConfig srcConfig, SkColorSpace* srcColorSpace,
return false;
}
- bool applyPremulToSrc = false;
- if (kUnpremul_PixelOpsFlag & pixelOpsFlags) {
- if (!GrPixelConfigIs8888Unorm(srcConfig) && kRGBA_half_GrPixelConfig != srcConfig) {
- return false;
- }
- applyPremulToSrc = true;
+ bool applyPremulToSrc = SkToBool(kUnpremul_PixelOpsFlag & pixelOpsFlags);
+ if (applyPremulToSrc && !valid_unpremul_config(srcConfig)) {
+ return false;
}
// We don't allow conversion between integer configs and float/fixed configs.
if (GrPixelConfigIsSint(surface->config()) != GrPixelConfigIsSint(srcConfig)) {
if (tempProxy) {
sk_sp<GrFragmentProcessor> fp;
if (applyPremulToSrc) {
- fp = this->createUPMToPMEffect(tempProxy, tempDrawInfo.fSwizzle, SkMatrix::I());
+ fp = this->createUPMToPMEffect(tempProxy, SkMatrix::I());
+ fp = GrFragmentProcessor::SwizzleOutput(std::move(fp), tempDrawInfo.fSwizzle);
// If premultiplying was the only reason for the draw, fall back to a straight write.
if (!fp) {
if (GrGpu::kCallerPrefersDraw_DrawPreference == drawPreference) {
}
if (tempProxy) {
if (!fp) {
- fp = GrConfigConversionEffect::Make(this->resourceProvider(),
- tempProxy, tempDrawInfo.fSwizzle,
- GrConfigConversionEffect::kNone_PMConversion,
- SkMatrix::I());
+ fp = GrSimpleTextureEffect::Make(this->resourceProvider(), tempProxy, nullptr,
+ SkMatrix::I());
+ fp = GrFragmentProcessor::SwizzleOutput(std::move(fp), tempDrawInfo.fSwizzle);
+
if (!fp) {
return false;
}
}
bool unpremul = SkToBool(kUnpremul_PixelOpsFlag & flags);
- if (unpremul && !GrPixelConfigIs8888Unorm(dstConfig) && kRGBA_half_GrPixelConfig != dstConfig) {
+ if (unpremul && !valid_unpremul_config(dstConfig)) {
// The unpremul flag is only allowed for 8888 and F16 configs.
return false;
}
SkMatrix textureMatrix = SkMatrix::MakeTrans(SkIntToScalar(left), SkIntToScalar(top));
sk_sp<GrFragmentProcessor> fp;
if (unpremul) {
- fp = this->createPMToUPMEffect(src->asTexture(), tempDrawInfo.fSwizzle,
- textureMatrix);
+ fp = this->createPMToUPMEffect(src->asTexture(), textureMatrix);
+ fp = GrFragmentProcessor::SwizzleOutput(std::move(fp), tempDrawInfo.fSwizzle);
if (fp) {
unpremul = false; // we no longer need to do this on CPU after the read back.
} else if (GrGpu::kCallerPrefersDraw_DrawPreference == drawPreference) {
}
}
if (!fp && tempRTC) {
- fp = GrConfigConversionEffect::Make(src->asTexture(), tempDrawInfo.fSwizzle,
- GrConfigConversionEffect::kNone_PMConversion,
- textureMatrix);
+ fp = GrSimpleTextureEffect::Make(src->asTexture(), nullptr, textureMatrix);
+ fp = GrFragmentProcessor::SwizzleOutput(std::move(fp), tempDrawInfo.fSwizzle);
}
if (fp) {
GrPaint paint;
}
sk_sp<GrFragmentProcessor> GrContext::createPMToUPMEffect(GrTexture* texture,
- const GrSwizzle& swizzle,
const SkMatrix& matrix) {
ASSERT_SINGLE_OWNER
// We should have already called this->testPMConversionsIfNecessary().
SkASSERT(fDidTestPMConversions);
if (kRGBA_half_GrPixelConfig == texture->config()) {
- SkASSERT(swizzle == GrSwizzle::RGBA());
return GrFragmentProcessor::UnpremulOutput(
GrSimpleTextureEffect::Make(texture, nullptr, matrix));
} else {
GrConfigConversionEffect::PMConversion pmToUPM =
static_cast<GrConfigConversionEffect::PMConversion>(fPMToUPMConversion);
- if (GrConfigConversionEffect::kNone_PMConversion != pmToUPM) {
- return GrConfigConversionEffect::Make(texture, swizzle, pmToUPM, matrix);
+ if (GrConfigConversionEffect::kPMConversionCnt != pmToUPM) {
+ return GrConfigConversionEffect::Make(texture, pmToUPM, matrix);
} else {
return nullptr;
}
}
sk_sp<GrFragmentProcessor> GrContext::createPMToUPMEffect(sk_sp<GrTextureProxy> proxy,
- const GrSwizzle& swizzle,
const SkMatrix& matrix) {
ASSERT_SINGLE_OWNER
// We should have already called this->testPMConversionsIfNecessary().
SkASSERT(fDidTestPMConversions);
if (kRGBA_half_GrPixelConfig == proxy->config()) {
- SkASSERT(swizzle == GrSwizzle::RGBA());
return GrFragmentProcessor::UnpremulOutput(
GrSimpleTextureEffect::Make(this->resourceProvider(), std::move(proxy),
nullptr, matrix));
} else {
GrConfigConversionEffect::PMConversion pmToUPM =
static_cast<GrConfigConversionEffect::PMConversion>(fPMToUPMConversion);
- if (GrConfigConversionEffect::kNone_PMConversion != pmToUPM) {
+ if (GrConfigConversionEffect::kPMConversionCnt != pmToUPM) {
return GrConfigConversionEffect::Make(this->resourceProvider(), std::move(proxy),
- swizzle, pmToUPM, matrix);
+ pmToUPM, matrix);
} else {
return nullptr;
}
}
sk_sp<GrFragmentProcessor> GrContext::createUPMToPMEffect(sk_sp<GrTextureProxy> proxy,
- const GrSwizzle& swizzle,
const SkMatrix& matrix) {
ASSERT_SINGLE_OWNER
// We should have already called this->testPMConversionsIfNecessary().
SkASSERT(fDidTestPMConversions);
if (kRGBA_half_GrPixelConfig == proxy->config()) {
- SkASSERT(swizzle == GrSwizzle::RGBA());
return GrFragmentProcessor::PremulOutput(
GrSimpleTextureEffect::Make(this->resourceProvider(), std::move(proxy),
nullptr, matrix));
} else {
GrConfigConversionEffect::PMConversion upmToPM =
static_cast<GrConfigConversionEffect::PMConversion>(fUPMToPMConversion);
- if (GrConfigConversionEffect::kNone_PMConversion != upmToPM) {
+ if (GrConfigConversionEffect::kPMConversionCnt != upmToPM) {
return GrConfigConversionEffect::Make(this->resourceProvider(), std::move(proxy),
- swizzle, upmToPM, matrix);
+ upmToPM, matrix);
} else {
return nullptr;
}
SkASSERT(fDidTestPMConversions);
// The PM<->UPM tests fail or succeed together so we only need to check one.
// For F16, we always allow PM/UPM conversion on the GPU, even if it doesn't round-trip.
- return GrConfigConversionEffect::kNone_PMConversion != fPMToUPMConversion ||
+ return GrConfigConversionEffect::kPMConversionCnt != fPMToUPMConversion ||
kRGBA_half_GrPixelConfig == config;
}
public:
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.
args.fTransformedCoords[0].getType());
fragBuilder->codeAppend(";");
- if (GrConfigConversionEffect::kNone_PMConversion == pmConversion) {
- SkASSERT(GrSwizzle::RGBA() != swizzle);
- fragBuilder->codeAppendf("%s = %s.%s;", args.fOutputColor, tmpVar.c_str(),
- swizzle.c_str());
- } else {
- switch (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());
- 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());
-
- 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());
- 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());
- break;
- default:
- SkFAIL("Unknown conversion op.");
- break;
- }
- fragBuilder->codeAppendf("%s = %s.%s;", args.fOutputColor, tmpVar.c_str(),
- swizzle.c_str());
+ switch (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());
+ 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());
+
+ 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());
+ 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());
+ 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());
static inline void GenKey(const GrProcessor& processor, const GrShaderCaps&,
GrProcessorKeyBuilder* b) {
const GrConfigConversionEffect& cce = processor.cast<GrConfigConversionEffect>();
- uint32_t key = (cce.swizzle().asKey()) | (cce.pmConversion() << 16);
+ uint32_t key = cce.pmConversion();
b->add32(key);
}
///////////////////////////////////////////////////////////////////////////////
GrConfigConversionEffect::GrConfigConversionEffect(GrTexture* texture,
- const GrSwizzle& swizzle,
PMConversion pmConversion,
const SkMatrix& matrix)
: INHERITED(texture, nullptr, matrix, kNone_OptimizationFlags)
- , 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
// conversion.
- SkASSERT((kRGBA_8888_GrPixelConfig == texture->config() ||
- kBGRA_8888_GrPixelConfig == texture->config()) ||
- kNone_PMConversion == pmConversion);
- // Why did we pollute our texture cache instead of using a GrSingleTextureEffect?
- SkASSERT(swizzle != GrSwizzle::RGBA() || kNone_PMConversion != pmConversion);
+ SkASSERT(kRGBA_8888_GrPixelConfig == texture->config() ||
+ kBGRA_8888_GrPixelConfig == texture->config());
}
GrConfigConversionEffect::GrConfigConversionEffect(GrResourceProvider* resourceProvider,
- sk_sp<GrTextureProxy>
- proxy,
- const GrSwizzle& swizzle,
+ sk_sp<GrTextureProxy> proxy,
PMConversion pmConversion,
const SkMatrix& matrix)
: INHERITED(resourceProvider, kNone_OptimizationFlags, proxy, nullptr, matrix)
- , 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
// conversion.
- SkASSERT((kRGBA_8888_GrPixelConfig == proxy->config() ||
- kBGRA_8888_GrPixelConfig == proxy->config()) ||
- kNone_PMConversion == pmConversion);
- // Why did we pollute our texture cache instead of using a GrSingleTextureEffect?
- SkASSERT(swizzle != GrSwizzle::RGBA() || kNone_PMConversion != pmConversion);
+ SkASSERT(kRGBA_8888_GrPixelConfig == proxy->config() ||
+ kBGRA_8888_GrPixelConfig == proxy->config());
}
bool GrConfigConversionEffect::onIsEqual(const GrFragmentProcessor& s) const {
const GrConfigConversionEffect& other = s.cast<GrConfigConversionEffect>();
- return other.fSwizzle == fSwizzle &&
- other.fPMConversion == fPMConversion;
+ return other.fPMConversion == fPMConversion;
}
///////////////////////////////////////////////////////////////////////////////
#if GR_TEST_UTILS
sk_sp<GrFragmentProcessor> GrConfigConversionEffect::TestCreate(GrProcessorTestData* d) {
PMConversion pmConv = static_cast<PMConversion>(d->fRandom->nextULessThan(kPMConversionCnt));
- GrSwizzle swizzle;
- do {
- swizzle = GrSwizzle::CreateRandom(d->fRandom);
- } while (pmConv == kNone_PMConversion && swizzle == GrSwizzle::RGBA());
return sk_sp<GrFragmentProcessor>(new GrConfigConversionEffect(
d->resourceProvider(),
d->textureProxy(GrProcessorUnitTest::kSkiaPMTextureIdx),
- swizzle, pmConv, GrTest::TestMatrix(d->fRandom)));
+ pmConv, GrTest::TestMatrix(d->fRandom)));
}
#endif
void GrConfigConversionEffect::TestForPreservingPMConversions(GrContext* context,
PMConversion* pmToUPMRule,
PMConversion* upmToPMRule) {
- *pmToUPMRule = kNone_PMConversion;
- *upmToPMRule = kNone_PMConversion;
+ *pmToUPMRule = kPMConversionCnt;
+ *upmToPMRule = kPMConversionCnt;
static constexpr int kSize = 256;
static constexpr GrPixelConfig kConfig = kRGBA_8888_GrPixelConfig;
SkAutoTMalloc<uint32_t> data(kSize * kSize * 3);
desc.fHeight = kSize;
desc.fConfig = kConfig;
- sk_sp<GrTextureProxy> dataProxy = GrSurfaceProxy::MakeDeferred(context->resourceProvider(),
- desc, SkBudgeted::kYes, data, 0);
+ GrResourceProvider* resourceProvider = context->resourceProvider();
+ sk_sp<GrTextureProxy> dataProxy = GrSurfaceProxy::MakeDeferred(resourceProvider, desc,
+ SkBudgeted::kYes, data, 0);
if (!dataProxy) {
return;
}
GrPaint paint2;
GrPaint paint3;
sk_sp<GrFragmentProcessor> pmToUPM1(new GrConfigConversionEffect(
- context->resourceProvider(), dataProxy, GrSwizzle::RGBA(),
- *pmToUPMRule, SkMatrix::I()));
+ resourceProvider, dataProxy, *pmToUPMRule, SkMatrix::I()));
sk_sp<GrFragmentProcessor> upmToPM(new GrConfigConversionEffect(
- context->resourceProvider(), readRTC->asTextureProxyRef(), GrSwizzle::RGBA(),
- *upmToPMRule, SkMatrix::I()));
+ resourceProvider, readRTC->asTextureProxyRef(), *upmToPMRule, SkMatrix::I()));
sk_sp<GrFragmentProcessor> pmToUPM2(new GrConfigConversionEffect(
- context->resourceProvider(), tempRTC->asTextureProxyRef(), GrSwizzle::RGBA(),
- *pmToUPMRule, SkMatrix::I()));
+ resourceProvider, tempRTC->asTextureProxyRef(), *pmToUPMRule, SkMatrix::I()));
paint1.addColorFragmentProcessor(std::move(pmToUPM1));
paint1.setPorterDuffXPFactory(SkBlendMode::kSrc);
}
}
if (failed) {
- *pmToUPMRule = kNone_PMConversion;
- *upmToPMRule = kNone_PMConversion;
+ *pmToUPMRule = kPMConversionCnt;
+ *upmToPMRule = kPMConversionCnt;
}
}
sk_sp<GrFragmentProcessor> GrConfigConversionEffect::Make(GrTexture* texture,
- const GrSwizzle& swizzle,
PMConversion pmConversion,
const SkMatrix& matrix) {
- 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.
- return GrSimpleTextureEffect::Make(texture, nullptr, matrix);
- } else {
- if (kRGBA_8888_GrPixelConfig != texture->config() &&
- kBGRA_8888_GrPixelConfig != texture->config() &&
- kNone_PMConversion != pmConversion) {
- // The PM conversions assume colors are 0..255
- return nullptr;
- }
- return sk_sp<GrFragmentProcessor>(
- new GrConfigConversionEffect(texture, swizzle, pmConversion, matrix));
+ if (kRGBA_8888_GrPixelConfig != texture->config() &&
+ kBGRA_8888_GrPixelConfig != texture->config()) {
+ // The PM conversions assume colors are 0..255
+ return nullptr;
}
+ return sk_sp<GrFragmentProcessor>(
+ new GrConfigConversionEffect(texture, pmConversion, matrix));
}
sk_sp<GrFragmentProcessor> GrConfigConversionEffect::Make(GrResourceProvider* resourceProvider,
sk_sp<GrTextureProxy> proxy,
- const GrSwizzle& swizzle,
PMConversion pmConversion,
const SkMatrix& matrix) {
- 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.
- return GrSimpleTextureEffect::Make(resourceProvider, std::move(proxy), nullptr, matrix);
- } else {
- if (kRGBA_8888_GrPixelConfig != proxy->config() &&
- kBGRA_8888_GrPixelConfig != proxy->config() &&
- kNone_PMConversion != pmConversion) {
- // The PM conversions assume colors are 0..255
- return nullptr;
- }
- return sk_sp<GrFragmentProcessor>(new GrConfigConversionEffect(resourceProvider,
- std::move(proxy), swizzle,
- pmConversion, matrix));
+ if (kRGBA_8888_GrPixelConfig != proxy->config() &&
+ kBGRA_8888_GrPixelConfig != proxy->config()) {
+ // The PM conversions assume colors are 0..255
+ return nullptr;
}
+ return sk_sp<GrFragmentProcessor>(new GrConfigConversionEffect(resourceProvider,
+ std::move(proxy),
+ pmConversion, matrix));
}