diff options
author | bsalomon <bsalomon@google.com> | 2014-10-27 12:53:08 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2014-10-27 12:53:08 -0700 |
commit | c6327a8f7e7e282c0b3a95049c75db7a8f92c693 (patch) | |
tree | 998c2fca0957d329d3c2c6796b70f85aee350ecc /src/effects | |
parent | 96c60686eef6fc514feba6136f1b475f71dbf3ec (diff) |
stuff
BUG=skia:
Review URL: https://codereview.chromium.org/655913003
Diffstat (limited to 'src/effects')
-rw-r--r-- | src/effects/SkTableColorFilter.cpp | 137 | ||||
-rw-r--r-- | src/effects/gradients/SkGradientShader.cpp | 3 |
2 files changed, 114 insertions, 26 deletions
diff --git a/src/effects/SkTableColorFilter.cpp b/src/effects/SkTableColorFilter.cpp index ca2757f299..e4daf20b00 100644 --- a/src/effects/SkTableColorFilter.cpp +++ b/src/effects/SkTableColorFilter.cpp @@ -277,17 +277,17 @@ bool SkTable_ColorFilter::asComponentTable(SkBitmap* table) const { #include "GrFragmentProcessor.h" #include "GrTBackendProcessorFactory.h" +#include "SkGr.h" +#include "effects/GrTextureStripAtlas.h" #include "gl/GrGLProcessor.h" #include "gl/builders/GrGLProgramBuilder.h" -#include "SkGr.h" + class GLColorTableEffect; class ColorTableEffect : public GrFragmentProcessor { public: - static GrFragmentProcessor* Create(GrTexture* texture, unsigned flags) { - return SkNEW_ARGS(ColorTableEffect, (texture, flags)); - } + static GrFragmentProcessor* Create(GrContext* context, SkBitmap bitmap, unsigned flags); virtual ~ColorTableEffect(); @@ -296,18 +296,25 @@ public: typedef GLColorTableEffect GLProcessor; + const GrTextureStripAtlas* atlas() const { return fAtlas; } + int atlasRow() const { return fRow; } + private: - virtual bool onIsEqual(const GrFragmentProcessor&) const SK_OVERRIDE{ return true; } + virtual bool onIsEqual(const GrFragmentProcessor&) const SK_OVERRIDE; virtual void onComputeInvariantOutput(InvariantOutput* inout) const SK_OVERRIDE; - explicit ColorTableEffect(GrTexture* texture, unsigned flags); + ColorTableEffect(GrTexture* texture, GrTextureStripAtlas* atlas, int row, unsigned flags); GR_DECLARE_FRAGMENT_PROCESSOR_TEST; - GrTextureAccess fTextureAccess; - unsigned fFlags; // currently not used in shader code, just to assist - // onComputeInvariantOutput(). + GrTextureAccess fTextureAccess; + + // currently not used in shader code, just to assist onComputeInvariantOutput(). + unsigned fFlags; + + GrTextureStripAtlas* fAtlas; + int fRow; typedef GrFragmentProcessor INHERITED; }; @@ -324,12 +331,12 @@ public: const TransformedCoordsArray&, const TextureSamplerArray&) SK_OVERRIDE; - virtual void setData(const GrGLProgramDataManager&, const GrProcessor&) SK_OVERRIDE {} + virtual void setData(const GrGLProgramDataManager&, const GrProcessor&) SK_OVERRIDE; static void GenKey(const GrProcessor&, const GrGLCaps&, GrProcessorKeyBuilder* b) {} private: - + UniformHandle fRGBAYValuesUni; typedef GrGLFragmentProcessor INHERITED; }; @@ -337,6 +344,25 @@ GLColorTableEffect::GLColorTableEffect(const GrBackendProcessorFactory& factory, : INHERITED(factory) { } +void GLColorTableEffect::setData(const GrGLProgramDataManager& pdm, const GrProcessor& proc) { + // The textures are organized in a strip where the rows are ordered a, r, g, b. + float rgbaYValues[4]; + const ColorTableEffect& cte = proc.cast<ColorTableEffect>(); + if (cte.atlas()) { + SkScalar yDelta = cte.atlas()->getNormalizedTexelHeight(); + rgbaYValues[3] = cte.atlas()->getYOffset(cte.atlasRow()) + SK_ScalarHalf * yDelta; + rgbaYValues[0] = rgbaYValues[3] + yDelta; + rgbaYValues[1] = rgbaYValues[0] + yDelta; + rgbaYValues[2] = rgbaYValues[1] + yDelta; + } else { + rgbaYValues[3] = 0.125; + rgbaYValues[0] = 0.375; + rgbaYValues[1] = 0.625; + rgbaYValues[2] = 0.875; + } + pdm.set4fv(fRGBAYValuesUni, 1, rgbaYValues); +} + void GLColorTableEffect::emitCode(GrGLFPBuilder* builder, const GrFragmentProcessor&, const GrProcessorKey&, @@ -344,7 +370,9 @@ void GLColorTableEffect::emitCode(GrGLFPBuilder* builder, const char* inputColor, const TransformedCoordsArray&, const TextureSamplerArray& samplers) { - + const char* yoffsets; + fRGBAYValuesUni = builder->addUniform(GrGLFPBuilder::kFragment_Visibility, + kVec4f_GrSLType, "yoffsets", &yoffsets); static const float kColorScaleFactor = 255.0f / 256.0f; static const float kColorOffsetFactor = 1.0f / 512.0f; GrGLFPFragmentBuilder* fsBuilder = builder->getFragmentShaderBuilder(); @@ -363,40 +391,84 @@ void GLColorTableEffect::emitCode(GrGLFPBuilder* builder, kColorOffsetFactor, kColorOffsetFactor); } + SkString coord; + fsBuilder->codeAppendf("\t\t%s.a = ", outputColor); - fsBuilder->appendTextureLookup(samplers[0], "vec2(coord.a, 0.125)"); + coord.printf("vec2(coord.a, %s.a)", yoffsets); + fsBuilder->appendTextureLookup(samplers[0], coord.c_str()); fsBuilder->codeAppend(";\n"); fsBuilder->codeAppendf("\t\t%s.r = ", outputColor); - fsBuilder->appendTextureLookup(samplers[0], "vec2(coord.r, 0.375)"); + coord.printf("vec2(coord.r, %s.r)", yoffsets); + fsBuilder->appendTextureLookup(samplers[0], coord.c_str()); fsBuilder->codeAppend(";\n"); fsBuilder->codeAppendf("\t\t%s.g = ", outputColor); - fsBuilder->appendTextureLookup(samplers[0], "vec2(coord.g, 0.625)"); + coord.printf("vec2(coord.g, %s.g)", yoffsets); + fsBuilder->appendTextureLookup(samplers[0], coord.c_str()); fsBuilder->codeAppend(";\n"); fsBuilder->codeAppendf("\t\t%s.b = ", outputColor); - fsBuilder->appendTextureLookup(samplers[0], "vec2(coord.b, 0.875)"); + coord.printf("vec2(coord.b, %s.b)", yoffsets); + fsBuilder->appendTextureLookup(samplers[0], coord.c_str()); fsBuilder->codeAppend(";\n"); fsBuilder->codeAppendf("\t\t%s.rgb *= %s.a;\n", outputColor, outputColor); } /////////////////////////////////////////////////////////////////////////////// +GrFragmentProcessor* ColorTableEffect::Create(GrContext* context, SkBitmap bitmap, unsigned flags) { + + GrTextureStripAtlas::Desc desc; + desc.fWidth = bitmap.width(); + desc.fHeight = 128; + desc.fRowHeight = bitmap.height(); + desc.fContext = context; + desc.fConfig = SkImageInfo2GrPixelConfig(bitmap.info()); + GrTextureStripAtlas* atlas = GrTextureStripAtlas::GetAtlas(desc); + int row = atlas->lockRow(bitmap); + SkAutoTUnref<GrTexture> texture; + if (-1 == row) { + atlas = NULL; + // Passing params=NULL because this effect does no tiling or filtering. + texture.reset(GrRefCachedBitmapTexture(context, bitmap, NULL)); + } else { + texture.reset(SkRef(atlas->getTexture())); + } + + return SkNEW_ARGS(ColorTableEffect, (texture, atlas, row, flags)); +} -ColorTableEffect::ColorTableEffect(GrTexture* texture, unsigned flags) +ColorTableEffect::ColorTableEffect(GrTexture* texture, GrTextureStripAtlas* atlas, int row, + unsigned flags) : fTextureAccess(texture, "a") - , fFlags(flags) { + , fFlags(flags) + , fAtlas(atlas) + , fRow(row) { + this->addTextureAccess(&fTextureAccess); } ColorTableEffect::~ColorTableEffect() { + if (fAtlas) { + fAtlas->unlockRow(fRow); + } } const GrBackendFragmentProcessorFactory& ColorTableEffect::getFactory() const { return GrTBackendFragmentProcessorFactory<ColorTableEffect>::getInstance(); } +bool ColorTableEffect::onIsEqual(const GrFragmentProcessor& other) const { + // For non-atlased instances, the texture (compared by base class) is sufficient to + // differentiate different tables. For atlased instances we ensure they are using the + // same row. + const ColorTableEffect& that = other.cast<ColorTableEffect>(); + SkASSERT(SkToBool(fAtlas) == SkToBool(that.fAtlas)); + // Ok to always do this comparison since both would be -1 if non-atlased. + return fRow == that.fRow; +} + void ColorTableEffect::onComputeInvariantOutput(InvariantOutput* inout) const { // If we kept the table in the effect then we could actually run known inputs through the // table. @@ -424,17 +496,34 @@ GrFragmentProcessor* ColorTableEffect::TestCreate(SkRandom* random, GrContext* context, const GrDrawTargetCaps&, GrTexture* textures[]) { - static unsigned kAllFlags = SkTable_ColorFilter::kR_Flag | SkTable_ColorFilter::kG_Flag | - SkTable_ColorFilter::kB_Flag | SkTable_ColorFilter::kA_Flag; - return ColorTableEffect::Create(textures[GrProcessorUnitTest::kAlphaTextureIdx], kAllFlags); + int flags = 0; + uint8_t luts[256][4]; + do { + for (int i = 0; i < 4; ++i) { + flags |= random->nextBool() ? (1 << i): 0; + } + } while (!flags); + for (int i = 0; i < 4; ++i) { + if (flags & (1 << i)) { + for (int j = 0; j < 256; ++j) { + luts[j][i] = SkToU8(random->nextBits(8)); + } + } + } + SkAutoTUnref<SkColorFilter> filter(SkTableColorFilter::CreateARGB( + (flags & (1 << 0)) ? luts[0] : NULL, + (flags & (1 << 1)) ? luts[1] : NULL, + (flags & (1 << 2)) ? luts[2] : NULL, + (flags & (1 << 3)) ? luts[3] : NULL + )); + return filter->asFragmentProcessor(context); } GrFragmentProcessor* SkTable_ColorFilter::asFragmentProcessor(GrContext* context) const { SkBitmap bitmap; this->asComponentTable(&bitmap); - // passing NULL because this effect does no tiling or filtering. - SkAutoTUnref<GrTexture> texture(GrRefCachedBitmapTexture(context, bitmap, NULL)); - return texture ? ColorTableEffect::Create(texture, fFlags) : NULL; + + return ColorTableEffect::Create(context, bitmap, fFlags); } #endif // SK_SUPPORT_GPU diff --git a/src/effects/gradients/SkGradientShader.cpp b/src/effects/gradients/SkGradientShader.cpp index 9dce5c2e0f..0d1730860a 100644 --- a/src/effects/gradients/SkGradientShader.cpp +++ b/src/effects/gradients/SkGradientShader.cpp @@ -1159,8 +1159,7 @@ GrGradientEffect::GrGradientEffect(GrContext* ctx, fRow = fAtlas->lockRow(bitmap); if (-1 != fRow) { - fYCoord = fAtlas->getYOffset(fRow) + SK_ScalarHalf * - fAtlas->getVerticalScaleFactor(); + fYCoord = fAtlas->getYOffset(fRow) + SK_ScalarHalf * fAtlas->getNormalizedTexelHeight(); fCoordTransform.reset(kCoordSet, matrix, fAtlas->getTexture()); fTextureAccess.reset(fAtlas->getTexture(), params); } else { |