GrBicubicEffect.cpp revision 77af6805e5faea1e2a5c0220098aec9082f3a6e5
13aad3b01afc77993ff051c02e49186294e312980humper@google.com#include "GrBicubicEffect.h" 23aad3b01afc77993ff051c02e49186294e312980humper@google.com 33aad3b01afc77993ff051c02e49186294e312980humper@google.com#define DS(x) SkDoubleToScalar(x) 43aad3b01afc77993ff051c02e49186294e312980humper@google.com 53aad3b01afc77993ff051c02e49186294e312980humper@google.comconst SkScalar GrBicubicEffect::gMitchellCoefficients[16] = { 63aad3b01afc77993ff051c02e49186294e312980humper@google.com DS( 1.0 / 18.0), DS(-9.0 / 18.0), DS( 15.0 / 18.0), DS( -7.0 / 18.0), 73aad3b01afc77993ff051c02e49186294e312980humper@google.com DS(16.0 / 18.0), DS( 0.0 / 18.0), DS(-36.0 / 18.0), DS( 21.0 / 18.0), 83aad3b01afc77993ff051c02e49186294e312980humper@google.com DS( 1.0 / 18.0), DS( 9.0 / 18.0), DS( 27.0 / 18.0), DS(-21.0 / 18.0), 93aad3b01afc77993ff051c02e49186294e312980humper@google.com DS( 0.0 / 18.0), DS( 0.0 / 18.0), DS( -6.0 / 18.0), DS( 7.0 / 18.0), 103aad3b01afc77993ff051c02e49186294e312980humper@google.com}; 113aad3b01afc77993ff051c02e49186294e312980humper@google.com 123aad3b01afc77993ff051c02e49186294e312980humper@google.com 133aad3b01afc77993ff051c02e49186294e312980humper@google.comclass GrGLBicubicEffect : public GrGLEffect { 143aad3b01afc77993ff051c02e49186294e312980humper@google.compublic: 153aad3b01afc77993ff051c02e49186294e312980humper@google.com GrGLBicubicEffect(const GrBackendEffectFactory& factory, 163aad3b01afc77993ff051c02e49186294e312980humper@google.com const GrDrawEffect&); 173aad3b01afc77993ff051c02e49186294e312980humper@google.com virtual void emitCode(GrGLShaderBuilder*, 183aad3b01afc77993ff051c02e49186294e312980humper@google.com const GrDrawEffect&, 193aad3b01afc77993ff051c02e49186294e312980humper@google.com EffectKey, 203aad3b01afc77993ff051c02e49186294e312980humper@google.com const char* outputColor, 213aad3b01afc77993ff051c02e49186294e312980humper@google.com const char* inputColor, 2277af6805e5faea1e2a5c0220098aec9082f3a6e5bsalomon@google.com const TransformedCoordsArray&, 233aad3b01afc77993ff051c02e49186294e312980humper@google.com const TextureSamplerArray&) SK_OVERRIDE; 243aad3b01afc77993ff051c02e49186294e312980humper@google.com 253aad3b01afc77993ff051c02e49186294e312980humper@google.com virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVERRIDE; 263aad3b01afc77993ff051c02e49186294e312980humper@google.com 273aad3b01afc77993ff051c02e49186294e312980humper@google.comprivate: 283aad3b01afc77993ff051c02e49186294e312980humper@google.com typedef GrGLUniformManager::UniformHandle UniformHandle; 293aad3b01afc77993ff051c02e49186294e312980humper@google.com 303aad3b01afc77993ff051c02e49186294e312980humper@google.com UniformHandle fCoefficientsUni; 313aad3b01afc77993ff051c02e49186294e312980humper@google.com UniformHandle fImageIncrementUni; 323aad3b01afc77993ff051c02e49186294e312980humper@google.com 333aad3b01afc77993ff051c02e49186294e312980humper@google.com typedef GrGLEffect INHERITED; 343aad3b01afc77993ff051c02e49186294e312980humper@google.com}; 353aad3b01afc77993ff051c02e49186294e312980humper@google.com 3677af6805e5faea1e2a5c0220098aec9082f3a6e5bsalomon@google.comGrGLBicubicEffect::GrGLBicubicEffect(const GrBackendEffectFactory& factory, const GrDrawEffect&) 3777af6805e5faea1e2a5c0220098aec9082f3a6e5bsalomon@google.com : INHERITED(factory) { 383aad3b01afc77993ff051c02e49186294e312980humper@google.com} 393aad3b01afc77993ff051c02e49186294e312980humper@google.com 403aad3b01afc77993ff051c02e49186294e312980humper@google.comvoid GrGLBicubicEffect::emitCode(GrGLShaderBuilder* builder, 413aad3b01afc77993ff051c02e49186294e312980humper@google.com const GrDrawEffect&, 423aad3b01afc77993ff051c02e49186294e312980humper@google.com EffectKey key, 433aad3b01afc77993ff051c02e49186294e312980humper@google.com const char* outputColor, 443aad3b01afc77993ff051c02e49186294e312980humper@google.com const char* inputColor, 4577af6805e5faea1e2a5c0220098aec9082f3a6e5bsalomon@google.com const TransformedCoordsArray& coords, 463aad3b01afc77993ff051c02e49186294e312980humper@google.com const TextureSamplerArray& samplers) { 4777af6805e5faea1e2a5c0220098aec9082f3a6e5bsalomon@google.com SkString coords2D = builder->ensureFSCoords2D(coords, 0); 483aad3b01afc77993ff051c02e49186294e312980humper@google.com fCoefficientsUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility, 493aad3b01afc77993ff051c02e49186294e312980humper@google.com kMat44f_GrSLType, "Coefficients"); 503aad3b01afc77993ff051c02e49186294e312980humper@google.com fImageIncrementUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility, 513aad3b01afc77993ff051c02e49186294e312980humper@google.com kVec2f_GrSLType, "ImageIncrement"); 523aad3b01afc77993ff051c02e49186294e312980humper@google.com 533aad3b01afc77993ff051c02e49186294e312980humper@google.com const char* imgInc = builder->getUniformCStr(fImageIncrementUni); 543aad3b01afc77993ff051c02e49186294e312980humper@google.com const char* coeff = builder->getUniformCStr(fCoefficientsUni); 553aad3b01afc77993ff051c02e49186294e312980humper@google.com 563aad3b01afc77993ff051c02e49186294e312980humper@google.com SkString cubicBlendName; 573aad3b01afc77993ff051c02e49186294e312980humper@google.com 583aad3b01afc77993ff051c02e49186294e312980humper@google.com static const GrGLShaderVar gCubicBlendArgs[] = { 593aad3b01afc77993ff051c02e49186294e312980humper@google.com GrGLShaderVar("coefficients", kMat44f_GrSLType), 603aad3b01afc77993ff051c02e49186294e312980humper@google.com GrGLShaderVar("t", kFloat_GrSLType), 613aad3b01afc77993ff051c02e49186294e312980humper@google.com GrGLShaderVar("c0", kVec4f_GrSLType), 623aad3b01afc77993ff051c02e49186294e312980humper@google.com GrGLShaderVar("c1", kVec4f_GrSLType), 633aad3b01afc77993ff051c02e49186294e312980humper@google.com GrGLShaderVar("c2", kVec4f_GrSLType), 643aad3b01afc77993ff051c02e49186294e312980humper@google.com GrGLShaderVar("c3", kVec4f_GrSLType), 653aad3b01afc77993ff051c02e49186294e312980humper@google.com }; 663aad3b01afc77993ff051c02e49186294e312980humper@google.com builder->fsEmitFunction(kVec4f_GrSLType, 673aad3b01afc77993ff051c02e49186294e312980humper@google.com "cubicBlend", 683aad3b01afc77993ff051c02e49186294e312980humper@google.com SK_ARRAY_COUNT(gCubicBlendArgs), 693aad3b01afc77993ff051c02e49186294e312980humper@google.com gCubicBlendArgs, 703aad3b01afc77993ff051c02e49186294e312980humper@google.com "\tvec4 ts = vec4(1.0, t, t * t, t * t * t);\n" 713aad3b01afc77993ff051c02e49186294e312980humper@google.com "\tvec4 c = coefficients * ts;\n" 723aad3b01afc77993ff051c02e49186294e312980humper@google.com "\treturn c.x * c0 + c.y * c1 + c.z * c2 + c.w * c3;\n", 733aad3b01afc77993ff051c02e49186294e312980humper@google.com &cubicBlendName); 7477af6805e5faea1e2a5c0220098aec9082f3a6e5bsalomon@google.com builder->fsCodeAppendf("\tvec2 coord = %s - %s * vec2(0.5, 0.5);\n", coords2D.c_str(), imgInc); 753aad3b01afc77993ff051c02e49186294e312980humper@google.com builder->fsCodeAppendf("\tvec2 f = fract(coord / %s);\n", imgInc); 763aad3b01afc77993ff051c02e49186294e312980humper@google.com for (int y = 0; y < 4; ++y) { 773aad3b01afc77993ff051c02e49186294e312980humper@google.com for (int x = 0; x < 4; ++x) { 783aad3b01afc77993ff051c02e49186294e312980humper@google.com SkString coord; 793aad3b01afc77993ff051c02e49186294e312980humper@google.com coord.printf("coord + %s * vec2(%d, %d)", imgInc, x - 1, y - 1); 803aad3b01afc77993ff051c02e49186294e312980humper@google.com builder->fsCodeAppendf("\tvec4 s%d%d = ", x, y); 813aad3b01afc77993ff051c02e49186294e312980humper@google.com builder->fsAppendTextureLookup(samplers[0], coord.c_str()); 823aad3b01afc77993ff051c02e49186294e312980humper@google.com builder->fsCodeAppend(";\n"); 833aad3b01afc77993ff051c02e49186294e312980humper@google.com } 843aad3b01afc77993ff051c02e49186294e312980humper@google.com builder->fsCodeAppendf("\tvec4 s%d = %s(%s, f.x, s0%d, s1%d, s2%d, s3%d);\n", y, cubicBlendName.c_str(), coeff, y, y, y, y); 853aad3b01afc77993ff051c02e49186294e312980humper@google.com } 863aad3b01afc77993ff051c02e49186294e312980humper@google.com builder->fsCodeAppendf("\t%s = %s(%s, f.y, s0, s1, s2, s3);\n", outputColor, cubicBlendName.c_str(), coeff); 873aad3b01afc77993ff051c02e49186294e312980humper@google.com} 883aad3b01afc77993ff051c02e49186294e312980humper@google.com 893aad3b01afc77993ff051c02e49186294e312980humper@google.comvoid GrGLBicubicEffect::setData(const GrGLUniformManager& uman, 903aad3b01afc77993ff051c02e49186294e312980humper@google.com const GrDrawEffect& drawEffect) { 913aad3b01afc77993ff051c02e49186294e312980humper@google.com const GrBicubicEffect& effect = drawEffect.castEffect<GrBicubicEffect>(); 923aad3b01afc77993ff051c02e49186294e312980humper@google.com GrTexture& texture = *effect.texture(0); 933aad3b01afc77993ff051c02e49186294e312980humper@google.com float imageIncrement[2]; 943aad3b01afc77993ff051c02e49186294e312980humper@google.com imageIncrement[0] = 1.0f / texture.width(); 953aad3b01afc77993ff051c02e49186294e312980humper@google.com imageIncrement[1] = 1.0f / texture.height(); 963aad3b01afc77993ff051c02e49186294e312980humper@google.com uman.set2fv(fImageIncrementUni, 0, 1, imageIncrement); 973aad3b01afc77993ff051c02e49186294e312980humper@google.com uman.setMatrix4f(fCoefficientsUni, effect.coefficients()); 983aad3b01afc77993ff051c02e49186294e312980humper@google.com} 993aad3b01afc77993ff051c02e49186294e312980humper@google.com 1003aad3b01afc77993ff051c02e49186294e312980humper@google.comGrBicubicEffect::GrBicubicEffect(GrTexture* texture, 1013aad3b01afc77993ff051c02e49186294e312980humper@google.com const SkScalar coefficients[16]) 1023aad3b01afc77993ff051c02e49186294e312980humper@google.com : INHERITED(texture, MakeDivByTextureWHMatrix(texture)) { 1033aad3b01afc77993ff051c02e49186294e312980humper@google.com for (int y = 0; y < 4; y++) { 1043aad3b01afc77993ff051c02e49186294e312980humper@google.com for (int x = 0; x < 4; x++) { 1053aad3b01afc77993ff051c02e49186294e312980humper@google.com // Convert from row-major scalars to column-major floats. 1063aad3b01afc77993ff051c02e49186294e312980humper@google.com fCoefficients[x * 4 + y] = SkScalarToFloat(coefficients[y * 4 + x]); 1073aad3b01afc77993ff051c02e49186294e312980humper@google.com } 1083aad3b01afc77993ff051c02e49186294e312980humper@google.com } 1093aad3b01afc77993ff051c02e49186294e312980humper@google.com} 1103aad3b01afc77993ff051c02e49186294e312980humper@google.com 1113aad3b01afc77993ff051c02e49186294e312980humper@google.comGrBicubicEffect::GrBicubicEffect(GrTexture* texture, 1123aad3b01afc77993ff051c02e49186294e312980humper@google.com const SkScalar coefficients[16], 1133aad3b01afc77993ff051c02e49186294e312980humper@google.com const SkMatrix &matrix, 1143aad3b01afc77993ff051c02e49186294e312980humper@google.com const GrTextureParams ¶ms, 11577af6805e5faea1e2a5c0220098aec9082f3a6e5bsalomon@google.com GrCoordSet coordSet) 11677af6805e5faea1e2a5c0220098aec9082f3a6e5bsalomon@google.com : INHERITED(texture, MakeDivByTextureWHMatrix(texture), params, coordSet) { 1173aad3b01afc77993ff051c02e49186294e312980humper@google.com for (int y = 0; y < 4; y++) { 1183aad3b01afc77993ff051c02e49186294e312980humper@google.com for (int x = 0; x < 4; x++) { 1193aad3b01afc77993ff051c02e49186294e312980humper@google.com // Convert from row-major scalars to column-major floats. 1203aad3b01afc77993ff051c02e49186294e312980humper@google.com fCoefficients[x * 4 + y] = SkScalarToFloat(coefficients[y * 4 + x]); 1213aad3b01afc77993ff051c02e49186294e312980humper@google.com } 1223aad3b01afc77993ff051c02e49186294e312980humper@google.com } 1233aad3b01afc77993ff051c02e49186294e312980humper@google.com} 1243aad3b01afc77993ff051c02e49186294e312980humper@google.com 1253aad3b01afc77993ff051c02e49186294e312980humper@google.comGrBicubicEffect::~GrBicubicEffect() { 1263aad3b01afc77993ff051c02e49186294e312980humper@google.com} 1273aad3b01afc77993ff051c02e49186294e312980humper@google.com 1283aad3b01afc77993ff051c02e49186294e312980humper@google.comconst GrBackendEffectFactory& GrBicubicEffect::getFactory() const { 1293aad3b01afc77993ff051c02e49186294e312980humper@google.com return GrTBackendEffectFactory<GrBicubicEffect>::getInstance(); 1303aad3b01afc77993ff051c02e49186294e312980humper@google.com} 1313aad3b01afc77993ff051c02e49186294e312980humper@google.com 1323aad3b01afc77993ff051c02e49186294e312980humper@google.combool GrBicubicEffect::onIsEqual(const GrEffect& sBase) const { 1333aad3b01afc77993ff051c02e49186294e312980humper@google.com const GrBicubicEffect& s = CastEffect<GrBicubicEffect>(sBase); 134d1af237d7d52e23bc08ccaf73eddaadddeab6758humper@google.com return this->textureAccess(0) == s.textureAccess(0) && 1353aad3b01afc77993ff051c02e49186294e312980humper@google.com !memcmp(fCoefficients, s.coefficients(), 16); 1363aad3b01afc77993ff051c02e49186294e312980humper@google.com} 1373aad3b01afc77993ff051c02e49186294e312980humper@google.com 1383aad3b01afc77993ff051c02e49186294e312980humper@google.comvoid GrBicubicEffect::getConstantColorComponents(GrColor* color, uint32_t* validFlags) const { 1393aad3b01afc77993ff051c02e49186294e312980humper@google.com // FIXME: Perhaps we can do better. 1403aad3b01afc77993ff051c02e49186294e312980humper@google.com *validFlags = 0; 1413aad3b01afc77993ff051c02e49186294e312980humper@google.com return; 1423aad3b01afc77993ff051c02e49186294e312980humper@google.com} 1433aad3b01afc77993ff051c02e49186294e312980humper@google.com 1443aad3b01afc77993ff051c02e49186294e312980humper@google.comGR_DEFINE_EFFECT_TEST(GrBicubicEffect); 1453aad3b01afc77993ff051c02e49186294e312980humper@google.com 146e0e7cfe44bb9d66d76120a79e5275c294bacaa22commit-bot@chromium.orgGrEffectRef* GrBicubicEffect::TestCreate(SkRandom* random, 1473aad3b01afc77993ff051c02e49186294e312980humper@google.com GrContext* context, 1483aad3b01afc77993ff051c02e49186294e312980humper@google.com const GrDrawTargetCaps&, 1493aad3b01afc77993ff051c02e49186294e312980humper@google.com GrTexture* textures[]) { 1503aad3b01afc77993ff051c02e49186294e312980humper@google.com int texIdx = random->nextBool() ? GrEffectUnitTest::kSkiaPMTextureIdx : 1513aad3b01afc77993ff051c02e49186294e312980humper@google.com GrEffectUnitTest::kAlphaTextureIdx; 1523aad3b01afc77993ff051c02e49186294e312980humper@google.com SkScalar coefficients[16]; 1533aad3b01afc77993ff051c02e49186294e312980humper@google.com for (int i = 0; i < 16; i++) { 1543aad3b01afc77993ff051c02e49186294e312980humper@google.com coefficients[i] = random->nextSScalar1(); 1553aad3b01afc77993ff051c02e49186294e312980humper@google.com } 1563aad3b01afc77993ff051c02e49186294e312980humper@google.com return GrBicubicEffect::Create(textures[texIdx], coefficients); 1573aad3b01afc77993ff051c02e49186294e312980humper@google.com} 158