GPU device preserves pixel values across read/write/read of unpremul pixel values
Review URL: http://codereview.appspot.com/5695047/
git-svn-id: http://skia.googlecode.com/svn/trunk@3237 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/src/gpu/gl/GrGpuGLShaders.cpp b/src/gpu/gl/GrGpuGLShaders.cpp
index 4093a0d..a0a2df5 100644
--- a/src/gpu/gl/GrGpuGLShaders.cpp
+++ b/src/gpu/gl/GrGpuGLShaders.cpp
@@ -173,8 +173,9 @@
static const int IN_CONFIG_FLAGS[] = {
StageDesc::kNone_InConfigFlag,
StageDesc::kSwapRAndB_InConfigFlag,
- StageDesc::kSwapRAndB_InConfigFlag | StageDesc::kMulRGBByAlpha_InConfigFlag,
- StageDesc::kMulRGBByAlpha_InConfigFlag,
+ StageDesc::kSwapRAndB_InConfigFlag |
+ StageDesc::kMulRGBByAlpha_RoundUp_InConfigFlag,
+ StageDesc::kMulRGBByAlpha_RoundDown_InConfigFlag,
StageDesc::kSmearAlpha_InConfigFlag,
};
GrGLProgram program;
@@ -210,7 +211,7 @@
pdesc.fExperimentalGS = this->getCaps().fGeometryShaderSupport &&
random_bool(&random);
#endif
- pdesc.fOutputPM = random_int(&random, ProgramDesc::kOutputPMCnt);
+ pdesc.fOutputConfig = random_int(&random, ProgramDesc::kOutputConfigCnt);
bool edgeAA = random_bool(&random);
if (edgeAA) {
@@ -264,17 +265,20 @@
stage.fOptFlags |= StageDesc::kNoPerspective_OptFlagBit;
}
stage.setEnabled(VertexUsesStage(s, pdesc.fVertexLayout));
+ static const uint32_t kMulByAlphaMask =
+ StageDesc::kMulRGBByAlpha_RoundUp_InConfigFlag |
+ StageDesc::kMulRGBByAlpha_RoundDown_InConfigFlag;
switch (stage.fFetchMode) {
case StageDesc::kSingle_FetchMode:
stage.fKernelWidth = 0;
break;
case StageDesc::kConvolution_FetchMode:
stage.fKernelWidth = random_int(&random, 2, 8);
- stage.fInConfigFlags &= ~StageDesc::kMulRGBByAlpha_InConfigFlag;
+ stage.fInConfigFlags &= ~kMulByAlphaMask;
break;
case StageDesc::k2x2_FetchMode:
stage.fKernelWidth = 0;
- stage.fInConfigFlags &= ~StageDesc::kMulRGBByAlpha_InConfigFlag;
+ stage.fInConfigFlags &= ~kMulByAlphaMask;
break;
}
}
@@ -1102,7 +1106,17 @@
}
}
if (GrPixelConfigIsUnpremultiplied(texture->config())) {
- stage.fInConfigFlags |= StageDesc::kMulRGBByAlpha_InConfigFlag;
+ // The shader generator assumes that color channels are bytes
+ // when rounding.
+ GrAssert(4 == GrBytesPerPixel(texture->config()));
+ if (kUpOnWrite_DownOnRead_UnpremulConversion ==
+ fUnpremulConversion) {
+ stage.fInConfigFlags |=
+ StageDesc::kMulRGBByAlpha_RoundDown_InConfigFlag;
+ } else {
+ stage.fInConfigFlags |=
+ StageDesc::kMulRGBByAlpha_RoundUp_InConfigFlag;
+ }
}
if (sampler.getFilter() == GrSamplerState::kConvolution_Filter) {
@@ -1120,9 +1134,18 @@
}
if (GrPixelConfigIsUnpremultiplied(drawState.getRenderTarget()->config())) {
- desc.fOutputPM = ProgramDesc::kNo_OutputPM;
+ // The shader generator assumes that color channels are bytes
+ // when rounding.
+ GrAssert(4 == GrBytesPerPixel(drawState.getRenderTarget()->config()));
+ if (kUpOnWrite_DownOnRead_UnpremulConversion == fUnpremulConversion) {
+ desc.fOutputConfig =
+ ProgramDesc::kUnpremultiplied_RoundUp_OutputConfig;
+ } else {
+ desc.fOutputConfig =
+ ProgramDesc::kUnpremultiplied_RoundDown_OutputConfig;
+ }
} else {
- desc.fOutputPM = ProgramDesc::kYes_OutputPM;
+ desc.fOutputConfig = ProgramDesc::kPremultiplied_OutputConfig;
}
desc.fDualSrcOutput = ProgramDesc::kNone_DualSrcOutput;