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

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

Issue 22854005: GPU Gradients (Closed) Base URL: https://skia.googlecode.com/svn/trunk
Patch Set: reverted defer flag to true 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 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)){
875 940
876 builder->fsCodeAppendf("\tvec2 coord = vec2(%s, %s);\n", 941 builder->fsCodeAppendf("\tvec4 colorTemp = mix(%s, %s, %s);\n",
877 gradientTValue, 942 builder->getUniformVariable(fColorStartUni).c_str (),
878 builder->getUniformVariable(fFSYUni).c_str()); 943 builder->getUniformVariable(fColorEndUni).c_str() ,
879 builder->fsCodeAppendf("\t%s = ", outputColor); 944 gradientTValue);
880 builder->appendTextureLookupAndModulate(GrGLShaderBuilder::kFragment_ShaderT ype, 945
881 inputColor, 946 SkString output, colorTemp;
882 sampler, 947 colorTemp.append("colorTemp");
883 "coord"); 948 builder->fsCodeAppendf("\t%s = ", outputColor);
884 builder->fsCodeAppend(";\n"); 949 GrGLSLModulatef<4>(&output, inputColor, colorTemp.c_str());
950 builder->fsCodeAppend(output.c_str());
951 builder->fsCodeAppend(";\n");
952
953
954 } else if (GrGradientEffect::kThree_ColorType == getColorType(key)){
955
956 builder->fsCodeAppendf("\tfloat oneMinus2t = 1.0 - (2.0 * (%s));\n",
957 gradientTValue);
958 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",
959 builder->getUniformVariable(fColorStartUni).c_str (),
960 builder->getUniformVariable(fColorMidUni).c_str() ,
961 builder->getUniformVariable(fColorEndUni).c_str() );
962
963 SkString output, colorTemp;
964 colorTemp.append("colorTemp");
965 builder->fsCodeAppendf("\t%s = ", outputColor);
966 GrGLSLModulatef<4>(&output, inputColor, colorTemp.c_str());
967 builder->fsCodeAppend(output.c_str());
968 builder->fsCodeAppend(";\n");
969
970 } else {
971 builder->fsCodeAppendf("\tvec2 coord = vec2(%s, %s);\n",
972 gradientTValue,
973 builder->getUniformVariable(fFSYUni).c_str());
974 builder->fsCodeAppendf("\t%s = ", outputColor);
975 builder->appendTextureLookupAndModulate(GrGLShaderBuilder::kFragment_Sha derType,
976 inputColor,
977 samplers[0],
978 "coord");
979 builder->fsCodeAppend(";\n");
980 }
885 } 981 }
886 982
887 ///////////////////////////////////////////////////////////////////// 983 /////////////////////////////////////////////////////////////////////
888 984
889 GrGradientEffect::GrGradientEffect(GrContext* ctx, 985 GrGradientEffect::GrGradientEffect(GrContext* ctx,
890 const SkGradientShaderBase& shader, 986 const SkGradientShaderBase& shader,
891 const SkMatrix& matrix, 987 const SkMatrix& matrix,
892 SkShader::TileMode tileMode) { 988 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 989
898 fMatrix = matrix;
899 990
900 SkBitmap bitmap; 991 SkBitmap bitmap;
901 shader.getGradientTableBitmap(&bitmap); 992 shader.getGradientTableBitmap(&bitmap);
902 993 fMatrix = matrix;
903 fIsOpaque = shader.isOpaque(); 994 fIsOpaque = shader.isOpaque();
904 995
905 GrTextureStripAtlas::Desc desc; 996 SkShader::GradientInfo info;
906 desc.fWidth = bitmap.width(); 997 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 998
914 // We always filter the gradient table. Each table is one row of a texture, so always y-clamp. 999 info.fColorCount = 3;
915 GrTextureParams params; 1000 info.fColors = &fColors[0];
916 params.setFilterMode(GrTextureParams::kBilerp_FilterMode); 1001 info.fColorOffsets = &pos[0];
917 params.setTileModeX(tileMode); 1002 shader.asAGradient(&info);
918 1003
919 fRow = fAtlas->lockRow(bitmap); 1004 if (2 == info.fColorCount) { // if 2 color
920 if (-1 != fRow) { 1005 fRow = -1; // flag for no atlas
921 fYCoord = fAtlas->getYOffset(fRow) + SK_ScalarHalf * 1006 fColorType = kTwo_ColorType;
922 fAtlas->getVerticalScaleFactor(); 1007 } else if (3 == info.fColorCount &&
923 fTextureAccess.reset(fAtlas->getTexture(), params); 1008 (SkScalarAbs(pos[1] - 0.5) < 0.01)) { // 3 color symmetric
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()){
reed1 2013/08/15 21:32:15 nit: Skia doesn't use this-> for fields, but it do
dierk 2013/08/16 16:59:56 Done.
1057
1058 if (kTwo_ColorType == this->fColorType) {
1059 if (this->getColors()[0] != s.getColors()[0] ||
1060 this->getColors()[1] != s.getColors()[1]) {
1061 return false;
1062 }
1063 } else if (kThree_ColorType == 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

Powered by Google App Engine
This is Rietveld 408576698