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

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

Issue 22854005: GPU Gradients (Closed) Base URL: https://skia.googlecode.com/svn/trunk
Patch Set: Using texture method for 3 color sweeps. 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
« no previous file with comments | « src/core/SkShader.cpp ('k') | src/effects/gradients/SkGradientShaderPriv.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 const SkColor* colors = e.getColors();
877 setColorUni(uman, fColorStartUni, colors[0]);
878 setColorUni(uman, fColorEndUni, colors[1]);
879
880 } else if (GrGradientEffect::kThree_ColorType == e.getColorType()){
881
882 fEffectMatrix.setData(uman, e.getMatrix(), drawEffect, NULL);
883 const SkColor* colors = e.getColors();
884 setColorUni(uman, fColorStartUni, colors[0]);
885 setColorUni(uman, fColorMidUni, colors[1]);
886 setColorUni(uman, fColorEndUni, colors[2]);
887
888 } else {
889
890 const GrTexture* texture = e.texture(0);
891 fEffectMatrix.setData(uman, e.getMatrix(), drawEffect, texture);
892
893 SkScalar yCoord = e.getYCoord();
894 if (yCoord != fCachedYCoord) {
895 uman.set1f(fFSYUni, yCoord);
896 fCachedYCoord = yCoord;
897 }
849 } 898 }
850 } 899 }
851 900
852 GrGLEffect::EffectKey GrGLGradientEffect::GenMatrixKey(const GrDrawEffect& drawE ffect) { 901
902 GrGLEffect::EffectKey GrGLGradientEffect::GenBaseGradientKey(const GrDrawEffect& drawEffect) {
853 const GrGradientEffect& e = drawEffect.castEffect<GrGradientEffect>(); 903 const GrGradientEffect& e = drawEffect.castEffect<GrGradientEffect>();
854 const GrTexture* texture = e.texture(0); 904 const GrTexture* texture = NULL;
855 return GrGLEffectMatrix::GenKey(e.getMatrix(), drawEffect, kCoordsType, text ure); 905
906 if (GrGradientEffect::kTexture_ColorType == e.getColorType()){
907 texture = e.texture(0);
908 }
909
910 EffectKey key = GrGLEffectMatrix::GenKey(e.getMatrix(), drawEffect, kCoordsT ype, texture);
911
912 if (GrGradientEffect::kTwo_ColorType == e.getColorType()) {
913 key = key | kTwoColorKey;
914 } else if (GrGradientEffect::kThree_ColorType == e.getColorType()){
915 key = key | kThreeColorKey;
916 }
917
918 return key;
856 } 919 }
857 920
858 void GrGLGradientEffect::setupMatrix(GrGLShaderBuilder* builder, 921 void GrGLGradientEffect::setupMatrix(GrGLShaderBuilder* builder,
859 EffectKey key, 922 EffectKey key,
860 const char** fsCoordName, 923 const char** fsCoordName,
861 const char** vsVaryingName, 924 const char** vsVaryingName,
862 GrSLType* vsVaryingType) { 925 GrSLType* vsVaryingType) {
863 fEffectMatrix.emitCodeMakeFSCoords2D(builder, 926 fEffectMatrix.emitCodeMakeFSCoords2D(builder,
864 key & kMatrixKeyMask, 927 key & kMatrixKeyMask,
865 fsCoordName, 928 fsCoordName,
866 vsVaryingName, 929 vsVaryingName,
867 vsVaryingType); 930 vsVaryingType);
868 } 931 }
869 932
870 void GrGLGradientEffect::emitColorLookup(GrGLShaderBuilder* builder, 933 void GrGLGradientEffect::emitColor(GrGLShaderBuilder* builder,
871 const char* gradientTValue, 934 const char* gradientTValue,
872 const char* outputColor, 935 EffectKey key,
873 const char* inputColor, 936 const char* outputColor,
874 const GrGLShaderBuilder::TextureSampler & sampler) { 937 const char* inputColor,
938 const GrGLShaderBuilder::TextureSamplerArray& samplers) {
939 if (GrGradientEffect::kTwo_ColorType == getColorType(key)){
940
941 builder->fsCodeAppendf("\tvec4 colorTemp = mix(%s, %s, %s);\n",
942 builder->getUniformVariable(fColorStartUni).c_str (),
943 builder->getUniformVariable(fColorEndUni).c_str() ,
944 gradientTValue);
875 945
876 builder->fsCodeAppendf("\tvec2 coord = vec2(%s, %s);\n", 946 SkString output, colorTemp;
877 gradientTValue, 947 colorTemp.append("colorTemp");
878 builder->getUniformVariable(fFSYUni).c_str()); 948 builder->fsCodeAppendf("\t%s = ", outputColor);
879 builder->fsCodeAppendf("\t%s = ", outputColor); 949 GrGLSLModulatef<4>(&output, inputColor, colorTemp.c_str());
880 builder->appendTextureLookupAndModulate(GrGLShaderBuilder::kFragment_ShaderT ype, 950 builder->fsCodeAppend(output.c_str());
881 inputColor, 951 builder->fsCodeAppend(";\n");
882 sampler, 952
883 "coord"); 953 } else if (GrGradientEffect::kThree_ColorType == getColorType(key)){
884 builder->fsCodeAppend(";\n"); 954
955 builder->fsCodeAppendf("\tfloat oneMinus2t = 1.0 - (2.0 * %s);\n",
956 gradientTValue);
957 builder->fsCodeAppendf("\tvec4 colorTemp = clamp(oneMinus2t, 0, 1) * %s +(1 - min(abs(oneMinus2t), 1)) * %s + clamp(-oneMinus2t, 0, 1) * %s;\n",
bsalomon 2013/08/15 19:21:18 more 1s and 0s that need .0
dierk 2013/08/15 19:56:51 Done.
958 builder->getUniformVariable(fColorStartUni).c_str (),
959 builder->getUniformVariable(fColorMidUni).c_str() ,
960 builder->getUniformVariable(fColorEndUni).c_str() );
961
962 SkString output, colorTemp;
963 colorTemp.append("colorTemp");
964 builder->fsCodeAppendf("\t%s = ", outputColor);
965 GrGLSLModulatef<4>(&output, inputColor, colorTemp.c_str());
966 builder->fsCodeAppend(output.c_str());
967 builder->fsCodeAppend(";\n");
968
969 } else {
970 builder->fsCodeAppendf("\tvec2 coord = vec2(%s, %s);\n",
971 gradientTValue,
972 builder->getUniformVariable(fFSYUni).c_str());
973 builder->fsCodeAppendf("\t%s = ", outputColor);
974 builder->appendTextureLookupAndModulate(GrGLShaderBuilder::kFragment_Sha derType,
975 inputColor,
976 samplers[0],
977 "coord");
978 builder->fsCodeAppend(";\n");
979 }
885 } 980 }
886 981
887 ///////////////////////////////////////////////////////////////////// 982 /////////////////////////////////////////////////////////////////////
888 983
889 GrGradientEffect::GrGradientEffect(GrContext* ctx, 984 GrGradientEffect::GrGradientEffect(GrContext* ctx,
890 const SkGradientShaderBase& shader, 985 const SkGradientShaderBase& shader,
891 const SkMatrix& matrix, 986 const SkMatrix& matrix,
892 SkShader::TileMode tileMode) { 987 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 988
898 fMatrix = matrix;
899 989
900 SkBitmap bitmap; 990 SkBitmap bitmap;
901 shader.getGradientTableBitmap(&bitmap); 991 shader.getGradientTableBitmap(&bitmap);
902 992 fMatrix = matrix;
903 fIsOpaque = shader.isOpaque(); 993 fIsOpaque = shader.isOpaque();
904 994
905 GrTextureStripAtlas::Desc desc; 995 SkShader::GradientInfo info;
906 desc.fWidth = bitmap.width(); 996 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 997
914 // We always filter the gradient table. Each table is one row of a texture, so always y-clamp. 998 info.fColorCount = 3;
915 GrTextureParams params; 999 info.fColors = &fColors[0];
916 params.setFilterMode(GrTextureParams::kBilerp_FilterMode); 1000 info.fColorOffsets = &pos[0];
917 params.setTileModeX(tileMode); 1001 SkShader::GradientType gradType = shader.asAGradient(&info);
918 1002
919 fRow = fAtlas->lockRow(bitmap); 1003 if (2 == info.fColorCount) { // if 2 color
920 if (-1 != fRow) { 1004 fRow = -1; // flag for no atlas
921 fYCoord = fAtlas->getYOffset(fRow) + SK_ScalarHalf * 1005 fColorType = kTwo_ColorType;
922 fAtlas->getVerticalScaleFactor(); 1006 } else if (3 == info.fColorCount &&
923 fTextureAccess.reset(fAtlas->getTexture(), params); 1007 gradType != SkShader::kSweep_GradientType &&
1008 (SkScalarAbs(pos[1] - 0.5) < 0.01)) { // 3 color symmetric (not s weep!)
1009 fRow = -1; // flag for no atlas
1010 fColorType = kThree_ColorType;
924 } else { 1011 } else {
925 GrTexture* texture = GrLockAndRefCachedBitmapTexture(ctx, bitmap, &param s); 1012 fColorType = kTexture_ColorType;
926 fTextureAccess.reset(texture, params); 1013
927 fYCoord = SK_ScalarHalf; 1014 GrTextureStripAtlas::Desc desc;
1015 desc.fWidth = bitmap.width();
1016 desc.fHeight = 32;
1017 desc.fRowHeight = bitmap.height();
1018 desc.fContext = ctx;
1019 desc.fConfig = SkBitmapConfig2GrPixelConfig(bitmap.config());
1020 fAtlas = GrTextureStripAtlas::GetAtlas(desc);
1021 GrAssert(NULL != fAtlas);
928 1022
929 // Unlock immediately, this is not great, but we don't have a way of 1023 // 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 1024 GrTextureParams params;
931 // the cache, but it'll still be ref'd until it's no longer being used. 1025 params.setFilterMode(GrTextureParams::kBilerp_FilterMode);
932 GrUnlockAndUnrefCachedBitmapTexture(texture); 1026 params.setTileModeX(tileMode);
1027
1028 fRow = fAtlas->lockRow(bitmap);
1029 if (-1 != fRow) {
1030 fYCoord = fAtlas->getYOffset(fRow) + SK_ScalarHalf *
1031 fAtlas->getVerticalScaleFactor();
1032 fTextureAccess.reset(fAtlas->getTexture(), params);
1033 } else {
1034 GrTexture* texture = GrLockAndRefCachedBitmapTexture(ctx, bitmap, &p arams);
1035 fTextureAccess.reset(texture, params);
1036 fYCoord = SK_ScalarHalf;
1037
1038 // Unlock immediately, this is not great, but we don't have a way of
1039 // knowing when else to unlock it currently, so it may get purged fr om
1040 // the cache, but it'll still be ref'd until it's no longer being us ed.
1041 GrUnlockAndUnrefCachedBitmapTexture(texture);
1042 }
1043 this->addTextureAccess(&fTextureAccess);
933 } 1044 }
934 this->addTextureAccess(&fTextureAccess);
935 } 1045 }
936 1046
937 GrGradientEffect::~GrGradientEffect() { 1047 GrGradientEffect::~GrGradientEffect() {
938 if (this->useAtlas()) { 1048 if (this->useAtlas()) {
939 fAtlas->unlockRow(fRow); 1049 fAtlas->unlockRow(fRow);
940 } 1050 }
941 } 1051 }
942 1052
943 bool GrGradientEffect::onIsEqual(const GrEffect& effect) const { 1053 bool GrGradientEffect::onIsEqual(const GrEffect& effect) const {
944 const GrGradientEffect& s = CastEffect<GrGradientEffect>(effect); 1054 const GrGradientEffect& s = CastEffect<GrGradientEffect>(effect);
945 return fTextureAccess.getTexture() == s.fTextureAccess.getTexture() && 1055
946 fTextureAccess.getParams().getTileModeX() == 1056 if (this->fColorType == s.getColorType()){
1057
1058 if (2 == this->fColorType) {
bsalomon 2013/08/15 19:25:29 Is this the bug? Shouldn't we be checking enum val
dierk 2013/08/15 19:56:51 Good catch, changed it the enum but I'm still seei
1059 if (this->getColors()[0] != s.getColors()[0] ||
1060 this->getColors()[1] != s.getColors()[1]) {
1061 return false;
1062 }
1063 } else if (3 == this->fColorType) {
1064 if (this->getColors()[0] != s.getColors()[0] ||
1065 this->getColors()[1] != s.getColors()[1] ||
1066 this->getColors()[2] != s.getColors()[2]) {
1067 return false;
1068 }
1069 }
1070
1071 return fTextureAccess.getTexture() == s.fTextureAccess.getTexture() &&
1072 fTextureAccess.getParams().getTileModeX() ==
947 s.fTextureAccess.getParams().getTileModeX() && 1073 s.fTextureAccess.getParams().getTileModeX() &&
948 this->useAtlas() == s.useAtlas() && 1074 this->useAtlas() == s.useAtlas() &&
949 fYCoord == s.getYCoord() && 1075 fYCoord == s.getYCoord() &&
950 fMatrix.cheapEqualTo(s.getMatrix()); 1076 fMatrix.cheapEqualTo(s.getMatrix());
1077 }
1078
1079 return false;
951 } 1080 }
952 1081
953 void GrGradientEffect::getConstantColorComponents(GrColor* color, uint32_t* vali dFlags) const { 1082 void GrGradientEffect::getConstantColorComponents(GrColor* color, uint32_t* vali dFlags) const {
954 if (fIsOpaque && (kA_GrColorComponentFlag & *validFlags) && 0xff == GrColorU npackA(*color)) { 1083 if (fIsOpaque && (kA_GrColorComponentFlag & *validFlags) && 0xff == GrColorU npackA(*color)) {
955 *validFlags = kA_GrColorComponentFlag; 1084 *validFlags = kA_GrColorComponentFlag;
956 } else { 1085 } else {
957 *validFlags = 0; 1086 *validFlags = 0;
958 } 1087 }
959 } 1088 }
960 1089
(...skipping 15 matching lines...) Expand all
976 (*stops)[i] = stop; 1105 (*stops)[i] = stop;
977 stop = i < outColors - 1 ? stop + random->nextUScalar1() * (1.f - st op) : 1.f; 1106 stop = i < outColors - 1 ? stop + random->nextUScalar1() * (1.f - st op) : 1.f;
978 } 1107 }
979 } 1108 }
980 *tm = static_cast<SkShader::TileMode>(random->nextULessThan(SkShader::kTileM odeCount)); 1109 *tm = static_cast<SkShader::TileMode>(random->nextULessThan(SkShader::kTileM odeCount));
981 1110
982 return outColors; 1111 return outColors;
983 } 1112 }
984 1113
985 #endif 1114 #endif
OLDNEW
« no previous file with comments | « src/core/SkShader.cpp ('k') | src/effects/gradients/SkGradientShaderPriv.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698