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/GrGLProgram.cpp b/src/gpu/gl/GrGLProgram.cpp
index 868149f..7eecf91 100644
--- a/src/gpu/gl/GrGLProgram.cpp
+++ b/src/gpu/gl/GrGLProgram.cpp
@@ -953,13 +953,22 @@
inCoverage.c_str(),
&segments.fFSCode);
}
- if (ProgramDesc::kNo_OutputPM == fProgramDesc.fOutputPM) {
- segments.fFSCode.appendf("\t%s = %s.a <= 0.0 ? vec4(0,0,0,0) : vec4(%s.rgb / %s.a, %s.a);\n",
- colorOutput.getName().c_str(),
- colorOutput.getName().c_str(),
- colorOutput.getName().c_str(),
- colorOutput.getName().c_str(),
- colorOutput.getName().c_str());
+ if (ProgramDesc::kUnpremultiplied_RoundDown_OutputConfig ==
+ fProgramDesc.fOutputConfig) {
+ segments.fFSCode.appendf("\t%s = %s.a <= 0.0 ? vec4(0,0,0,0) : vec4(floor(%s.rgb / %s.a * 255.0)/255.0, %s.a);\n",
+ colorOutput.getName().c_str(),
+ colorOutput.getName().c_str(),
+ colorOutput.getName().c_str(),
+ colorOutput.getName().c_str(),
+ colorOutput.getName().c_str());
+ } else if (ProgramDesc::kUnpremultiplied_RoundUp_OutputConfig ==
+ fProgramDesc.fOutputConfig) {
+ segments.fFSCode.appendf("\t%s = %s.a <= 0.0 ? vec4(0,0,0,0) : vec4(ceil(%s.rgb / %s.a * 255.0)/255.0, %s.a);\n",
+ colorOutput.getName().c_str(),
+ colorOutput.getName().c_str(),
+ colorOutput.getName().c_str(),
+ colorOutput.getName().c_str(),
+ colorOutput.getName().c_str());
}
}
@@ -1809,13 +1818,16 @@
};
+ static const uint32_t kMulByAlphaMask =
+ (StageDesc::kMulRGBByAlpha_RoundUp_InConfigFlag |
+ StageDesc::kMulRGBByAlpha_RoundDown_InConfigFlag);
+
const char* swizzle = "";
if (desc.fInConfigFlags & StageDesc::kSwapRAndB_InConfigFlag) {
GrAssert(!(desc.fInConfigFlags & StageDesc::kSmearAlpha_InConfigFlag));
swizzle = ".bgra";
} else if (desc.fInConfigFlags & StageDesc::kSmearAlpha_InConfigFlag) {
- GrAssert(!(desc.fInConfigFlags &
- StageDesc::kMulRGBByAlpha_InConfigFlag));
+ GrAssert(!(desc.fInConfigFlags & kMulByAlphaMask));
swizzle = ".aaaa";
}
@@ -1843,30 +1855,37 @@
switch (desc.fFetchMode) {
case StageDesc::k2x2_FetchMode:
- GrAssert(!(desc.fInConfigFlags &
- StageDesc::kMulRGBByAlpha_InConfigFlag));
+ GrAssert(!(desc.fInConfigFlags & kMulByAlphaMask));
gen2x2FS(stageNum, segments, locations, &sampleCoords,
samplerName, texelSizeName, swizzle, fsOutColor,
texFunc, modulate, complexCoord, coordDims);
break;
case StageDesc::kConvolution_FetchMode:
- GrAssert(!(desc.fInConfigFlags &
- StageDesc::kMulRGBByAlpha_InConfigFlag));
+ GrAssert(!(desc.fInConfigFlags & kMulByAlphaMask));
genConvolutionFS(stageNum, desc, segments,
samplerName, kernel, swizzle, imageIncrementName, fsOutColor,
sampleCoords, texFunc, modulate);
break;
default:
- if (desc.fInConfigFlags & StageDesc::kMulRGBByAlpha_InConfigFlag) {
+ if (desc.fInConfigFlags & kMulByAlphaMask) {
+ // only one of the mul by alpha flags should be set
+ GrAssert(GrIsPow2(kMulByAlphaMask & desc.fInConfigFlags));
GrAssert(!(desc.fInConfigFlags &
StageDesc::kSmearAlpha_InConfigFlag));
segments->fFSCode.appendf("\t%s = %s(%s, %s)%s;\n",
fsOutColor, texFunc.c_str(),
samplerName, sampleCoords.c_str(),
swizzle);
- segments->fFSCode.appendf("\t%s = vec4(%s.rgb*%s.a,%s.a)%s;\n",
- fsOutColor, fsOutColor, fsOutColor,
- fsOutColor, modulate.c_str());
+ if (desc.fInConfigFlags &
+ StageDesc::kMulRGBByAlpha_RoundUp_InConfigFlag) {
+ segments->fFSCode.appendf("\t%s = vec4(ceil(%s.rgb*%s.a*255.0)/255.0,%s.a)%s;\n",
+ fsOutColor, fsOutColor, fsOutColor,
+ fsOutColor, modulate.c_str());
+ } else {
+ segments->fFSCode.appendf("\t%s = vec4(floor(%s.rgb*%s.a*255.0)/255.0,%s.a)%s;\n",
+ fsOutColor, fsOutColor, fsOutColor,
+ fsOutColor, modulate.c_str());
+ }
} else {
segments->fFSCode.appendf("\t%s = %s(%s, %s)%s%s;\n",
fsOutColor, texFunc.c_str(),