aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/gpu/GrContext.cpp
diff options
context:
space:
mode:
authorGravatar Brian Osman <brianosman@google.com>2017-03-22 10:57:00 -0400
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2017-03-22 16:31:39 +0000
commitde1a60534648ca8a6eb3ae32e06a7a9e9c0591f3 (patch)
treeb198af69715b55724ca5e5f1b746db4fc7c11498 /src/gpu/GrContext.cpp
parentca0913ceb9a64d02e6fd6345e71af219f568430e (diff)
Support premul/unpremul of F16 during read/writePixels
Added PremulOutput and UnpremulOutput FP helpers. These are used (rather than GrConfigConversionEffect) when working with FP16 textures (and will also be used for other configs that can't be round-tripped via rounding). BUG=skia:5853 Change-Id: I101592c26c4f0b379d5e5a8678ef7b2f08e6ad56 Reviewed-on: https://skia-review.googlesource.com/9980 Reviewed-by: Brian Salomon <bsalomon@google.com> Commit-Queue: Brian Osman <brianosman@google.com>
Diffstat (limited to 'src/gpu/GrContext.cpp')
-rw-r--r--src/gpu/GrContext.cpp70
1 files changed, 46 insertions, 24 deletions
diff --git a/src/gpu/GrContext.cpp b/src/gpu/GrContext.cpp
index bcb93b30be..671376f089 100644
--- a/src/gpu/GrContext.cpp
+++ b/src/gpu/GrContext.cpp
@@ -266,7 +266,7 @@ bool GrContext::writeSurfacePixels(GrSurface* surface, SkColorSpace* dstColorSpa
bool applyPremulToSrc = false;
if (kUnpremul_PixelOpsFlag & pixelOpsFlags) {
- if (!GrPixelConfigIs8888Unorm(srcConfig)) {
+ if (!GrPixelConfigIs8888Unorm(srcConfig) && kRGBA_half_GrPixelConfig != srcConfig) {
return false;
}
applyPremulToSrc = true;
@@ -279,7 +279,7 @@ bool GrContext::writeSurfacePixels(GrSurface* surface, SkColorSpace* dstColorSpa
GrGpu::DrawPreference drawPreference = GrGpu::kNoDraw_DrawPreference;
// Don't prefer to draw for the conversion (and thereby access a texture from the cache) when
// we've already determined that there isn't a roundtrip preserving conversion processor pair.
- if (applyPremulToSrc && !this->didFailPMUPMConversionTest()) {
+ if (applyPremulToSrc && this->validPMUPMConversionExists(srcConfig)) {
drawPreference = GrGpu::kCallerPrefersDraw_DrawPreference;
}
@@ -422,8 +422,8 @@ bool GrContext::readSurfacePixels(GrSurface* src, SkColorSpace* srcColorSpace,
}
bool unpremul = SkToBool(kUnpremul_PixelOpsFlag & flags);
- if (unpremul && !GrPixelConfigIs8888Unorm(dstConfig)) {
- // The unpremul flag is only allowed for 8888 configs.
+ if (unpremul && !GrPixelConfigIs8888Unorm(dstConfig) && kRGBA_half_GrPixelConfig != dstConfig) {
+ // The unpremul flag is only allowed for 8888 and F16 configs.
return false;
}
// We don't allow conversion between integer configs and float/fixed configs.
@@ -434,7 +434,7 @@ bool GrContext::readSurfacePixels(GrSurface* src, SkColorSpace* srcColorSpace,
GrGpu::DrawPreference drawPreference = GrGpu::kNoDraw_DrawPreference;
// Don't prefer to draw for the conversion (and thereby access a texture from the cache) when
// we've already determined that there isn't a roundtrip preserving conversion processor pair.
- if (unpremul && !this->didFailPMUPMConversionTest()) {
+ if (unpremul && this->validPMUPMConversionExists(src->config())) {
drawPreference = GrGpu::kCallerPrefersDraw_DrawPreference;
}
@@ -865,12 +865,18 @@ sk_sp<GrFragmentProcessor> GrContext::createPMToUPMEffect(GrTexture* texture,
ASSERT_SINGLE_OWNER
// We should have already called this->testPMConversionsIfNecessary().
SkASSERT(fDidTestPMConversions);
- GrConfigConversionEffect::PMConversion pmToUPM =
- static_cast<GrConfigConversionEffect::PMConversion>(fPMToUPMConversion);
- if (GrConfigConversionEffect::kNone_PMConversion != pmToUPM) {
- return GrConfigConversionEffect::Make(texture, swizzle, pmToUPM, matrix);
+ if (kRGBA_half_GrPixelConfig == texture->config()) {
+ SkASSERT(swizzle == GrSwizzle::RGBA());
+ return GrFragmentProcessor::UnpremulOutput(
+ GrSimpleTextureEffect::Make(texture, nullptr, matrix));
} else {
- return nullptr;
+ GrConfigConversionEffect::PMConversion pmToUPM =
+ static_cast<GrConfigConversionEffect::PMConversion>(fPMToUPMConversion);
+ if (GrConfigConversionEffect::kNone_PMConversion != pmToUPM) {
+ return GrConfigConversionEffect::Make(texture, swizzle, pmToUPM, matrix);
+ } else {
+ return nullptr;
+ }
}
}
@@ -880,13 +886,20 @@ sk_sp<GrFragmentProcessor> GrContext::createPMToUPMEffect(sk_sp<GrTextureProxy>
ASSERT_SINGLE_OWNER
// We should have already called this->testPMConversionsIfNecessary().
SkASSERT(fDidTestPMConversions);
- GrConfigConversionEffect::PMConversion pmToUPM =
- static_cast<GrConfigConversionEffect::PMConversion>(fPMToUPMConversion);
- if (GrConfigConversionEffect::kNone_PMConversion != pmToUPM) {
- return GrConfigConversionEffect::Make(this->resourceProvider(),
- proxy, swizzle, pmToUPM, matrix);
+ if (kRGBA_half_GrPixelConfig == proxy->config()) {
+ SkASSERT(swizzle == GrSwizzle::RGBA());
+ return GrFragmentProcessor::UnpremulOutput(
+ GrSimpleTextureEffect::Make(this->resourceProvider(), std::move(proxy),
+ nullptr, matrix));
} else {
- return nullptr;
+ GrConfigConversionEffect::PMConversion pmToUPM =
+ static_cast<GrConfigConversionEffect::PMConversion>(fPMToUPMConversion);
+ if (GrConfigConversionEffect::kNone_PMConversion != pmToUPM) {
+ return GrConfigConversionEffect::Make(this->resourceProvider(), std::move(proxy),
+ swizzle, pmToUPM, matrix);
+ } else {
+ return nullptr;
+ }
}
}
@@ -896,22 +909,31 @@ sk_sp<GrFragmentProcessor> GrContext::createUPMToPMEffect(sk_sp<GrTextureProxy>
ASSERT_SINGLE_OWNER
// We should have already called this->testPMConversionsIfNecessary().
SkASSERT(fDidTestPMConversions);
- GrConfigConversionEffect::PMConversion upmToPM =
- static_cast<GrConfigConversionEffect::PMConversion>(fUPMToPMConversion);
- if (GrConfigConversionEffect::kNone_PMConversion != upmToPM) {
- return GrConfigConversionEffect::Make(this->resourceProvider(),
- std::move(proxy), swizzle, upmToPM, matrix);
+ if (kRGBA_half_GrPixelConfig == proxy->config()) {
+ SkASSERT(swizzle == GrSwizzle::RGBA());
+ return GrFragmentProcessor::PremulOutput(
+ GrSimpleTextureEffect::Make(this->resourceProvider(), std::move(proxy),
+ nullptr, matrix));
} else {
- return nullptr;
+ GrConfigConversionEffect::PMConversion upmToPM =
+ static_cast<GrConfigConversionEffect::PMConversion>(fUPMToPMConversion);
+ if (GrConfigConversionEffect::kNone_PMConversion != upmToPM) {
+ return GrConfigConversionEffect::Make(this->resourceProvider(), std::move(proxy),
+ swizzle, upmToPM, matrix);
+ } else {
+ return nullptr;
+ }
}
}
-bool GrContext::didFailPMUPMConversionTest() const {
+bool GrContext::validPMUPMConversionExists(GrPixelConfig config) const {
ASSERT_SINGLE_OWNER
// We should have already called this->testPMConversionsIfNecessary().
SkASSERT(fDidTestPMConversions);
// The PM<->UPM tests fail or succeed together so we only need to check one.
- return GrConfigConversionEffect::kNone_PMConversion == fPMToUPMConversion;
+ // For F16, we always allow PM/UPM conversion on the GPU, even if it doesn't round-trip.
+ return GrConfigConversionEffect::kNone_PMConversion != fPMToUPMConversion ||
+ kRGBA_half_GrPixelConfig == config;
}
//////////////////////////////////////////////////////////////////////////////