From b3a39b5b017eeb8a37ce5cb29c6e9b00d649d11b Mon Sep 17 00:00:00 2001 From: "senorblanco@chromium.org" Date: Thu, 5 Jan 2012 18:28:56 +0000 Subject: When applying a color matrix, unpremultiply the source, and premultiply the result. If the input color is missing, set to all-zeros or all-ones as appropriate. Add an alpha test case to the colormatrix GM. Review URL: http://codereview.appspot.com/5520046/ git-svn-id: http://skia.googlecode.com/svn/trunk@2974 2bbb7eff-a529-9590-31e7-b0007b416f81 --- gm/colormatrix.cpp | 13 +++++++++++++ src/gpu/GrGLProgram.cpp | 30 ++++++++++++++++++------------ src/gpu/GrGLProgram.h | 1 + 3 files changed, 32 insertions(+), 12 deletions(-) diff --git a/gm/colormatrix.cpp b/gm/colormatrix.cpp index 7d57b3278b..0a4acfd84f 100644 --- a/gm/colormatrix.cpp +++ b/gm/colormatrix.cpp @@ -90,6 +90,19 @@ protected: matrix.setYUV2RGB(); filter->setMatrix(matrix); canvas->drawBitmap(fBitmap, 80, 160, &paint); + + SkScalar s1 = SK_Scalar1; + SkScalar s255 = SkIntToScalar(255); + // Move red into alpha, set color to white + SkScalar data[20] = { + 0, 0, 0, 0, s255, + 0, 0, 0, 0, s255, + 0, 0, 0, 0, s255, + s1, 0, 0, 0, 0, + }; + + filter->setArray(data); + canvas->drawBitmap(fBitmap, 160, 160, &paint); } private: diff --git a/src/gpu/GrGLProgram.cpp b/src/gpu/GrGLProgram.cpp index ce87b857af..2e391e3c31 100644 --- a/src/gpu/GrGLProgram.cpp +++ b/src/gpu/GrGLProgram.cpp @@ -373,7 +373,8 @@ static void addColorFilter(GrStringBuilder* fsCode, const char * outputVar, */ static void addColorMatrix(GrStringBuilder* fsCode, const char * outputVar, const char* inColor) { - fsCode->appendf("%s = %s * %s + %s;\n", outputVar, COL_MATRIX_UNI_NAME, inColor, COL_MATRIX_VEC_UNI_NAME); + fsCode->appendf("\t%s = %s * vec4(%s.rgb / %s.a, %s.a) + %s;\n", outputVar, COL_MATRIX_UNI_NAME, inColor, inColor, inColor, COL_MATRIX_VEC_UNI_NAME); + fsCode->appendf("\t%s.rgb *= %s.a;\n", outputVar, outputVar); } namespace { @@ -652,6 +653,19 @@ void GrGLProgram::genGeometryShader(const GrGLInterface* gl, #endif } +const char* GrGLProgram::adjustInColor(const GrStringBuilder& inColor) const { + const char* color; + if (inColor.size()) { + return inColor.c_str(); + } else { + if (ProgramDesc::kSolidWhite_ColorInput == fProgramDesc.fColorInput) { + return all_ones_vec(4); + } else { + return all_zeros_vec(4); + } + } +} + bool GrGLProgram::genProgram(const GrGLInterface* gl, GrGLSLGeneration glslGeneration, GrGLProgram::CachedData* programData) const { @@ -818,16 +832,7 @@ bool GrGLProgram::genProgram(const GrGLInterface* gl, wroteFragColorZero = true; } else if (SkXfermode::kDst_Mode != fProgramDesc.fColorFilterXfermode) { segments.fFSCode.appendf("\tvec4 filteredColor;\n"); - const char* color; - if (inColor.size()) { - color = inColor.c_str(); - } else { - if (ProgramDesc::kSolidWhite_ColorInput == fProgramDesc.fColorInput) { - color = all_ones_vec(4); - } else { - color = all_zeros_vec(4); - } - } + const char* color = adjustInColor(inColor); addColorFilter(&segments.fFSCode, "filteredColor", uniformCoeff, colorCoeff, color); inColor = "filteredColor"; @@ -842,7 +847,8 @@ bool GrGLProgram::genProgram(const GrGLInterface* gl, programData->fUniLocations.fColorMatrixUni = kUseUniform; programData->fUniLocations.fColorMatrixVecUni = kUseUniform; segments.fFSCode.appendf("\tvec4 matrixedColor;\n"); - addColorMatrix(&segments.fFSCode, "matrixedColor", inColor.c_str()); + const char* color = adjustInColor(inColor); + addColorMatrix(&segments.fFSCode, "matrixedColor", color); inColor = "matrixedColor"; } diff --git a/src/gpu/GrGLProgram.h b/src/gpu/GrGLProgram.h index 7d19f7ad54..b4ad4af8c0 100644 --- a/src/gpu/GrGLProgram.h +++ b/src/gpu/GrGLProgram.h @@ -231,6 +231,7 @@ public: private: const ProgramDesc& getDesc() { return fProgramDesc; } + const char* adjustInColor(const GrStringBuilder& inColor) const; public: enum { -- cgit v1.2.3