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

Unified Diff: src/effects/SkTableColorFilter.cpp

Issue 655913003: Use texture strip atlas for color table filter (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: fix include order Created 6 years, 2 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | src/effects/gradients/SkGradientShader.cpp » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/effects/SkTableColorFilter.cpp
diff --git a/src/effects/SkTableColorFilter.cpp b/src/effects/SkTableColorFilter.cpp
index ca2757f299c7cc16c8cdd8e75582f7e2e10a3ace..e4daf20b006e11d92a59a681bd15409b8365c0a3 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"
reed1 2014/10/28 13:42:41 do we need to qualify this header's path? We don't
#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
« no previous file with comments | « no previous file | src/effects/gradients/SkGradientShader.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698