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 | |
parent | 96c60686eef6fc514feba6136f1b475f71dbf3ec (diff) |
stuff
BUG=skia:
Review URL: https://codereview.chromium.org/655913003
Diffstat (limited to 'src')
-rw-r--r-- | src/effects/SkTableColorFilter.cpp | 137 | ||||
-rw-r--r-- | src/effects/gradients/SkGradientShader.cpp | 3 | ||||
-rw-r--r-- | src/gpu/effects/GrTextureStripAtlas.cpp | 1 | ||||
-rw-r--r-- | src/gpu/effects/GrTextureStripAtlas.h | 8 |
4 files changed, 120 insertions, 29 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 { diff --git a/src/gpu/effects/GrTextureStripAtlas.cpp b/src/gpu/effects/GrTextureStripAtlas.cpp index 64ee711b36..385a580d43 100644 --- a/src/gpu/effects/GrTextureStripAtlas.cpp +++ b/src/gpu/effects/GrTextureStripAtlas.cpp @@ -80,6 +80,7 @@ GrTextureStripAtlas::GrTextureStripAtlas(GrTextureStripAtlas::Desc desc) , fLRUBack(NULL) { SkASSERT(fNumRows * fDesc.fRowHeight == fDesc.fHeight); this->initLRU(); + fNormalizedYHeight = SK_Scalar1 / fDesc.fHeight; VALIDATE; } diff --git a/src/gpu/effects/GrTextureStripAtlas.h b/src/gpu/effects/GrTextureStripAtlas.h index 58539fc0ac..80b33bbac4 100644 --- a/src/gpu/effects/GrTextureStripAtlas.h +++ b/src/gpu/effects/GrTextureStripAtlas.h @@ -61,11 +61,11 @@ public: * texture2D(sampler, vec2(x, yOffset + y * scaleFactor)) * * Where yOffset, returned by getYOffset(), is the offset to the start of the row within the - * atlas and scaleFactor, returned by getVerticalScaleFactor(), is the y-scale of the row, - * relative to the height of the overall atlas texture. + * atlas and scaleFactor, returned by getNormalizedTexelHeight, is the normalized height of + * one texel row. */ SkScalar getYOffset(int row) const { return SkIntToScalar(row) / fNumRows; } - SkScalar getVerticalScaleFactor() const { return SkIntToScalar(fDesc.fRowHeight) / fDesc.fHeight; } + SkScalar getNormalizedTexelHeight() const { return fNormalizedYHeight; } GrContext* getContext() const { return fDesc.fContext; } GrTexture* getTexture() const { return fTexture; } @@ -168,6 +168,8 @@ private: const uint16_t fNumRows; GrTexture* fTexture; + SkScalar fNormalizedYHeight; + // Array of AtlasRows which store the state of all our rows. Stored in a contiguous array, in // order that they appear in our texture, this means we can subtract this pointer from a row // pointer to get its index in the texture, and can save storing a row number in AtlasRow. |