From 717abfd2a9edcf57d07c42a03ed9f4c0062cd703 Mon Sep 17 00:00:00 2001 From: brianosman Date: Wed, 11 May 2016 11:43:35 -0700 Subject: [PATCH] Use GrGammaEffect to support YUV conversion without sRGB write control BUG=skia: Review-Url: https://codereview.chromium.org/1970833003 --- src/gpu/GrYUVProvider.cpp | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/src/gpu/GrYUVProvider.cpp b/src/gpu/GrYUVProvider.cpp index b4320d0b02..970644d0f4 100644 --- a/src/gpu/GrYUVProvider.cpp +++ b/src/gpu/GrYUVProvider.cpp @@ -8,6 +8,7 @@ #include "GrContext.h" #include "GrDrawContext.h" #include "GrYUVProvider.h" +#include "effects/GrGammaEffect.h" #include "effects/GrYUVEffect.h" #include "SkCachedData.h" @@ -120,9 +121,6 @@ sk_sp GrYUVProvider::refAsTexture(GrContext* ctx, } GrPaint paint; - // We may be decoding an sRGB image, but the result of our linear math on the YUV planes - // is already in sRGB in that case. Don't convert (which will make the image too bright). - paint.setDisableOutputConversionToSRGB(true); SkAutoTUnref yuvToRgbProcessor( GrYUVEffect::CreateYUVToRGB(yuvTextures[0], yuvTextures[1], @@ -130,6 +128,21 @@ sk_sp GrYUVProvider::refAsTexture(GrContext* ctx, yuvInfo.fSizeInfo.fSizes, yuvInfo.fColorSpace)); paint.addColorFragmentProcessor(yuvToRgbProcessor); + + // If we're decoding an sRGB image, the result of our linear math on the YUV planes is already + // in sRGB. (The encoding is just math on bytes, with no concept of color spaces.) So, we need + // to output the results of that math directly to the buffer that we will then consider sRGB. + // If we have sRGB write control, we can just tell the HW not to do the Linear -> sRGB step. + // Otherwise, we do our shader math to go from YUV -> sRGB, manually convert sRGB -> Linear, + // then let the HW convert Linear -> sRGB. + if (GrPixelConfigIsSRGB(desc.fConfig)) { + if (ctx->caps()->srgbWriteControl()) { + paint.setDisableOutputConversionToSRGB(true); + } else { + paint.addColorFragmentProcessor(GrGammaEffect::Create(2.2f))->unref(); + } + } + paint.setPorterDuffXPFactory(SkXfermode::kSrc_Mode); const SkRect r = SkRect::MakeIWH(yuvInfo.fSizeInfo.fSizes[SkYUVSizeInfo::kY].fWidth, yuvInfo.fSizeInfo.fSizes[SkYUVSizeInfo::kY].fHeight);