Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(511)

Side by Side Diff: src/effects/gradients/SkGradientShader.cpp

Issue 22854005: GPU Gradients (Closed) Base URL: https://skia.googlecode.com/svn/trunk
Patch Set: Added Mike's Suggestions Created 7 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 /* 1 /*
2 * Copyright 2006 The Android Open Source Project 2 * Copyright 2006 The Android Open Source Project
3 * 3 *
4 * Use of this source code is governed by a BSD-style license that can be 4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file. 5 * found in the LICENSE file.
6 */ 6 */
7 7
8 #include "SkGradientShaderPriv.h" 8 #include "SkGradientShaderPriv.h"
9 #include "SkLinearGradient.h" 9 #include "SkLinearGradient.h"
10 #include "SkRadialGradient.h" 10 #include "SkRadialGradient.h"
(...skipping 813 matching lines...) Expand 10 before | Expand all | Expand 10 after
824 #include "SkGr.h" 824 #include "SkGr.h"
825 825
826 GrGLGradientEffect::GrGLGradientEffect(const GrBackendEffectFactory& factory) 826 GrGLGradientEffect::GrGLGradientEffect(const GrBackendEffectFactory& factory)
827 : INHERITED(factory) 827 : INHERITED(factory)
828 , fCachedYCoord(SK_ScalarMax) 828 , fCachedYCoord(SK_ScalarMax)
829 , fEffectMatrix(kCoordsType) { 829 , fEffectMatrix(kCoordsType) {
830 } 830 }
831 831
832 GrGLGradientEffect::~GrGLGradientEffect() { } 832 GrGLGradientEffect::~GrGLGradientEffect() { }
833 833
834 void GrGLGradientEffect::emitYCoordUniform(GrGLShaderBuilder* builder) { 834 void GrGLGradientEffect::emitUniforms(GrGLShaderBuilder* builder, EffectKey key) {
835 fFSYUni = builder->addUniform(GrGLShaderBuilder::kFragment_ShaderType, 835
836 kFloat_GrSLType, "GradientYCoordFS"); 836 if (GrGradientEffect::kTwo_ColorType == getColorType(key)) { // 2 Color case
837 fColorStartUni = builder->addUniform(GrGLShaderBuilder::kFragment_Shader Type,
838 kVec4f_GrSLType, "GradientStartColo r");
839 fColorEndUni = builder->addUniform(GrGLShaderBuilder::kFragment_ShaderTy pe,
840 kVec4f_GrSLType, "GradientEndColor");
841
842 } else if (GrGradientEffect::kThree_ColorType == getColorType(key)){ // 3 Co lor Case
843 fColorStartUni = builder->addUniform(GrGLShaderBuilder::kFragment_Shader Type,
844 kVec4f_GrSLType, "GradientStartColo r");
845 fColorMidUni = builder->addUniform(GrGLShaderBuilder::kFragment_ShaderTy pe,
846 kVec4f_GrSLType, "GradientMidColor");
847 fColorEndUni = builder->addUniform(GrGLShaderBuilder::kFragment_ShaderTy pe,
848 kVec4f_GrSLType, "GradientEndColor" );
849
850 } else { // if not a fast case
851 fFSYUni = builder->addUniform(GrGLShaderBuilder::kFragment_ShaderType,
852 kFloat_GrSLType, "GradientYCoordFS");
853 }
854 }
855
856 static void setColorUni(const GrGLUniformManager& uman,
857 const GrGLUniformManager::UniformHandle uni,
858 const SkColor* color){
859 uman.set4f(uni,
860 SkColorGetR(*color)/255.f,
861 SkColorGetG(*color)/255.f,
862 SkColorGetB(*color)/255.f,
863 SkColorGetA(*color)/255.f
864 );
837 } 865 }
838 866
839 void GrGLGradientEffect::setData(const GrGLUniformManager& uman, 867 void GrGLGradientEffect::setData(const GrGLUniformManager& uman,
840 const GrDrawEffect& drawEffect) { 868 const GrDrawEffect& drawEffect) {
869
841 const GrGradientEffect& e = drawEffect.castEffect<GrGradientEffect>(); 870 const GrGradientEffect& e = drawEffect.castEffect<GrGradientEffect>();
842 const GrTexture* texture = e.texture(0);
843 fEffectMatrix.setData(uman, e.getMatrix(), drawEffect, texture);
844 871
845 SkScalar yCoord = e.getYCoord(); 872
846 if (yCoord != fCachedYCoord) { 873 if (GrGradientEffect::kTwo_ColorType == e.getColorType()){
847 uman.set1f(fFSYUni, yCoord); 874
848 fCachedYCoord = yCoord; 875 fEffectMatrix.setData(uman, e.getMatrix(), drawEffect, NULL);
876 setColorUni(uman, fColorStartUni, e.getColors(0));
877 setColorUni(uman, fColorEndUni, e.getColors(1));
878
879 } else if (GrGradientEffect::kThree_ColorType == e.getColorType()){
880
881 fEffectMatrix.setData(uman, e.getMatrix(), drawEffect, NULL);
882 setColorUni(uman, fColorStartUni, e.getColors(0));
883 setColorUni(uman, fColorMidUni, e.getColors(1));
884 setColorUni(uman, fColorEndUni, e.getColors(2));
885
886 } else {
887
888 const GrTexture* texture = e.texture(0);
889 fEffectMatrix.setData(uman, e.getMatrix(), drawEffect, texture);
890
891 SkScalar yCoord = e.getYCoord();
892 if (yCoord != fCachedYCoord) {
893 uman.set1f(fFSYUni, yCoord);
894 fCachedYCoord = yCoord;
895 }
849 } 896 }
850 } 897 }
851 898
852 GrGLEffect::EffectKey GrGLGradientEffect::GenMatrixKey(const GrDrawEffect& drawE ffect) { 899
900 GrGLEffect::EffectKey GrGLGradientEffect::GenBaseGradientKey(const GrDrawEffect& drawEffect) {
853 const GrGradientEffect& e = drawEffect.castEffect<GrGradientEffect>(); 901 const GrGradientEffect& e = drawEffect.castEffect<GrGradientEffect>();
854 const GrTexture* texture = e.texture(0); 902 const GrTexture* texture = NULL;
855 return GrGLEffectMatrix::GenKey(e.getMatrix(), drawEffect, kCoordsType, text ure); 903
904 if (GrGradientEffect::kTexture_ColorType == e.getColorType()){
905 texture = e.texture(0);
906 }
907
908 EffectKey key = GrGLEffectMatrix::GenKey(e.getMatrix(), drawEffect, kCoordsT ype, texture);
909
910 if (GrGradientEffect::kTwo_ColorType == e.getColorType()) {
911 key = key | kTwoColorKey;
912 } else if (GrGradientEffect::kThree_ColorType == e.getColorType()){
913 key = key | kThreeColorKey;
914 }
915
916 return key;
856 } 917 }
857 918
858 void GrGLGradientEffect::setupMatrix(GrGLShaderBuilder* builder, 919 void GrGLGradientEffect::setupMatrix(GrGLShaderBuilder* builder,
859 EffectKey key, 920 EffectKey key,
860 const char** fsCoordName, 921 const char** fsCoordName,
861 const char** vsVaryingName, 922 const char** vsVaryingName,
862 GrSLType* vsVaryingType) { 923 GrSLType* vsVaryingType) {
863 fEffectMatrix.emitCodeMakeFSCoords2D(builder, 924 fEffectMatrix.emitCodeMakeFSCoords2D(builder,
864 key & kMatrixKeyMask, 925 key & kMatrixKeyMask,
865 fsCoordName, 926 fsCoordName,
866 vsVaryingName, 927 vsVaryingName,
867 vsVaryingType); 928 vsVaryingType);
868 } 929 }
869 930
870 void GrGLGradientEffect::emitColorLookup(GrGLShaderBuilder* builder, 931 void GrGLGradientEffect::emitColor(GrGLShaderBuilder* builder,
871 const char* gradientTValue, 932 const char* gradientTValue,
872 const char* outputColor, 933 EffectKey key,
873 const char* inputColor, 934 const char* outputColor,
874 const GrGLShaderBuilder::TextureSampler & sampler) { 935 const char* inputColor,
936 const GrGLShaderBuilder::TextureSamplerArray& samplers) {
937 if (GrGradientEffect::kTwo_ColorType == getColorType(key)){
875 938
876 builder->fsCodeAppendf("\tvec2 coord = vec2(%s, %s);\n", 939 builder->fsCodeAppendf("\tvec4 colorTemp = mix(%s, %s, %s);\n",
877 gradientTValue, 940 builder->getUniformVariable(fColorStartUni).c_str (),
878 builder->getUniformVariable(fFSYUni).c_str()); 941 builder->getUniformVariable(fColorEndUni).c_str() ,
879 builder->fsCodeAppendf("\t%s = ", outputColor); 942 gradientTValue);
880 builder->appendTextureLookupAndModulate(GrGLShaderBuilder::kFragment_ShaderT ype, 943
881 inputColor, 944 SkString output, colorTemp;
882 sampler, 945 colorTemp.append("colorTemp");
883 "coord"); 946 builder->fsCodeAppendf("\t%s = ", outputColor);
884 builder->fsCodeAppend(";\n"); 947 GrGLSLModulatef<4>(&output, inputColor, colorTemp.c_str());
948 builder->fsCodeAppend(output.c_str());
949 builder->fsCodeAppend(";\n");
950
951
952 } else if (GrGradientEffect::kThree_ColorType == getColorType(key)){
953
954 builder->fsCodeAppendf("\tfloat oneMinus2t = 1.0 - (2.0 * (%s));\n",
955 gradientTValue);
956 builder->fsCodeAppendf("\tvec4 colorTemp = clamp(oneMinus2t, 0.0, 1.0) * %s +(1.0 - min(abs(oneMinus2t), 1.0)) * %s + clamp(-oneMinus2t, 0.0, 1.0) * %s; \n",
957 builder->getUniformVariable(fColorStartUni).c_str (),
958 builder->getUniformVariable(fColorMidUni).c_str() ,
959 builder->getUniformVariable(fColorEndUni).c_str() );
960
961 SkString output, colorTemp;
962 colorTemp.append("colorTemp");
963 builder->fsCodeAppendf("\t%s = ", outputColor);
964 GrGLSLModulatef<4>(&output, inputColor, colorTemp.c_str());
965 builder->fsCodeAppend(output.c_str());
966 builder->fsCodeAppend(";\n");
967
968 } else {
969 builder->fsCodeAppendf("\tvec2 coord = vec2(%s, %s);\n",
970 gradientTValue,
971 builder->getUniformVariable(fFSYUni).c_str());
972 builder->fsCodeAppendf("\t%s = ", outputColor);
973 builder->appendTextureLookupAndModulate(GrGLShaderBuilder::kFragment_Sha derType,
974 inputColor,
975 samplers[0],
976 "coord");
977 builder->fsCodeAppend(";\n");
978 }
885 } 979 }
886 980
887 ///////////////////////////////////////////////////////////////////// 981 /////////////////////////////////////////////////////////////////////
888 982
889 GrGradientEffect::GrGradientEffect(GrContext* ctx, 983 GrGradientEffect::GrGradientEffect(GrContext* ctx,
890 const SkGradientShaderBase& shader, 984 const SkGradientShaderBase& shader,
891 const SkMatrix& matrix, 985 const SkMatrix& matrix,
892 SkShader::TileMode tileMode) { 986 SkShader::TileMode tileMode) {
893 // TODO: check for simple cases where we don't need a texture:
894 //GradientInfo info;
895 //shader.asAGradient(&info);
896 //if (info.fColorCount == 2) { ...
897 987
898 fMatrix = matrix;
899 988
900 SkBitmap bitmap; 989 SkBitmap bitmap;
901 shader.getGradientTableBitmap(&bitmap); 990 shader.getGradientTableBitmap(&bitmap);
902 991 fMatrix = matrix;
903 fIsOpaque = shader.isOpaque(); 992 fIsOpaque = shader.isOpaque();
904 993
905 GrTextureStripAtlas::Desc desc; 994 SkShader::GradientInfo info;
906 desc.fWidth = bitmap.width(); 995 SkScalar pos[3] = {0};
907 desc.fHeight = 32;
908 desc.fRowHeight = bitmap.height();
909 desc.fContext = ctx;
910 desc.fConfig = SkBitmapConfig2GrPixelConfig(bitmap.config());
911 fAtlas = GrTextureStripAtlas::GetAtlas(desc);
912 SkASSERT(NULL != fAtlas);
913 996
914 // We always filter the gradient table. Each table is one row of a texture, so always y-clamp. 997 info.fColorCount = 3;
915 GrTextureParams params; 998 info.fColors = &fColors[0];
916 params.setFilterMode(GrTextureParams::kBilerp_FilterMode); 999 info.fColorOffsets = &pos[0];
917 params.setTileModeX(tileMode); 1000 shader.asAGradient(&info);
918 1001
919 fRow = fAtlas->lockRow(bitmap); 1002 if (2 == info.fColorCount) { // if 2 color
920 if (-1 != fRow) { 1003 fRow = -1; // flag for no atlas
921 fYCoord = fAtlas->getYOffset(fRow) + SK_ScalarHalf * 1004 fColorType = kTwo_ColorType;
922 fAtlas->getVerticalScaleFactor(); 1005 } else if (3 == info.fColorCount &&
923 fTextureAccess.reset(fAtlas->getTexture(), params); 1006 (SkScalarAbs(pos[1] - 0.5f) < 0.01f)) { // 3 color symmetric
1007 fRow = -1; // flag for no atlas
1008 fColorType = kThree_ColorType;
924 } else { 1009 } else {
925 GrTexture* texture = GrLockAndRefCachedBitmapTexture(ctx, bitmap, &param s); 1010 fColorType = kTexture_ColorType;
926 fTextureAccess.reset(texture, params); 1011
927 fYCoord = SK_ScalarHalf; 1012 GrTextureStripAtlas::Desc desc;
1013 desc.fWidth = bitmap.width();
1014 desc.fHeight = 32;
1015 desc.fRowHeight = bitmap.height();
1016 desc.fContext = ctx;
1017 desc.fConfig = SkBitmapConfig2GrPixelConfig(bitmap.config());
1018 fAtlas = GrTextureStripAtlas::GetAtlas(desc);
1019 GrAssert(NULL != fAtlas);
928 1020
929 // Unlock immediately, this is not great, but we don't have a way of 1021 // We always filter the gradient table. Each table is one row of a textu re, always y-clamp.
930 // knowing when else to unlock it currently, so it may get purged from 1022 GrTextureParams params;
931 // the cache, but it'll still be ref'd until it's no longer being used. 1023 params.setFilterMode(GrTextureParams::kBilerp_FilterMode);
932 GrUnlockAndUnrefCachedBitmapTexture(texture); 1024 params.setTileModeX(tileMode);
1025
1026 fRow = fAtlas->lockRow(bitmap);
1027 if (-1 != fRow) {
1028 fYCoord = fAtlas->getYOffset(fRow) + SK_ScalarHalf *
1029 fAtlas->getVerticalScaleFactor();
1030 fTextureAccess.reset(fAtlas->getTexture(), params);
1031 } else {
1032 GrTexture* texture = GrLockAndRefCachedBitmapTexture(ctx, bitmap, &p arams);
1033 fTextureAccess.reset(texture, params);
1034 fYCoord = SK_ScalarHalf;
1035
1036 // Unlock immediately, this is not great, but we don't have a way of
1037 // knowing when else to unlock it currently, so it may get purged fr om
1038 // the cache, but it'll still be ref'd until it's no longer being us ed.
1039 GrUnlockAndUnrefCachedBitmapTexture(texture);
1040 }
1041 this->addTextureAccess(&fTextureAccess);
933 } 1042 }
934 this->addTextureAccess(&fTextureAccess);
935 } 1043 }
936 1044
937 GrGradientEffect::~GrGradientEffect() { 1045 GrGradientEffect::~GrGradientEffect() {
938 if (this->useAtlas()) { 1046 if (this->useAtlas()) {
939 fAtlas->unlockRow(fRow); 1047 fAtlas->unlockRow(fRow);
940 } 1048 }
941 } 1049 }
942 1050
943 bool GrGradientEffect::onIsEqual(const GrEffect& effect) const { 1051 bool GrGradientEffect::onIsEqual(const GrEffect& effect) const {
944 const GrGradientEffect& s = CastEffect<GrGradientEffect>(effect); 1052 const GrGradientEffect& s = CastEffect<GrGradientEffect>(effect);
945 return fTextureAccess.getTexture() == s.fTextureAccess.getTexture() && 1053
946 fTextureAccess.getParams().getTileModeX() == 1054 if (this->fColorType == s.getColorType()){
1055
1056 if (kTwo_ColorType == fColorType) {
1057 if (*this->getColors(0) != *s.getColors(0) ||
1058 *this->getColors(1) != *s.getColors(1)) {
1059 return false;
1060 }
1061 } else if (kThree_ColorType == fColorType) {
1062 if (*this->getColors(0) != *s.getColors(0) ||
1063 *this->getColors(1) != *s.getColors(1) ||
1064 *this->getColors(2) != *s.getColors(2)) {
1065 return false;
1066 }
1067 }
1068
1069 return fTextureAccess.getTexture() == s.fTextureAccess.getTexture() &&
1070 fTextureAccess.getParams().getTileModeX() ==
947 s.fTextureAccess.getParams().getTileModeX() && 1071 s.fTextureAccess.getParams().getTileModeX() &&
948 this->useAtlas() == s.useAtlas() && 1072 this->useAtlas() == s.useAtlas() &&
949 fYCoord == s.getYCoord() && 1073 fYCoord == s.getYCoord() &&
950 fMatrix.cheapEqualTo(s.getMatrix()); 1074 fMatrix.cheapEqualTo(s.getMatrix());
1075 }
1076
1077 return false;
951 } 1078 }
952 1079
953 void GrGradientEffect::getConstantColorComponents(GrColor* color, uint32_t* vali dFlags) const { 1080 void GrGradientEffect::getConstantColorComponents(GrColor* color, uint32_t* vali dFlags) const {
954 if (fIsOpaque && (kA_GrColorComponentFlag & *validFlags) && 0xff == GrColorU npackA(*color)) { 1081 if (fIsOpaque && (kA_GrColorComponentFlag & *validFlags) && 0xff == GrColorU npackA(*color)) {
955 *validFlags = kA_GrColorComponentFlag; 1082 *validFlags = kA_GrColorComponentFlag;
956 } else { 1083 } else {
957 *validFlags = 0; 1084 *validFlags = 0;
958 } 1085 }
959 } 1086 }
960 1087
(...skipping 15 matching lines...) Expand all
976 (*stops)[i] = stop; 1103 (*stops)[i] = stop;
977 stop = i < outColors - 1 ? stop + random->nextUScalar1() * (1.f - st op) : 1.f; 1104 stop = i < outColors - 1 ? stop + random->nextUScalar1() * (1.f - st op) : 1.f;
978 } 1105 }
979 } 1106 }
980 *tm = static_cast<SkShader::TileMode>(random->nextULessThan(SkShader::kTileM odeCount)); 1107 *tm = static_cast<SkShader::TileMode>(random->nextULessThan(SkShader::kTileM odeCount));
981 1108
982 return outColors; 1109 return outColors;
983 } 1110 }
984 1111
985 #endif 1112 #endif
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698