aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorGravatar bsalomon <bsalomon@google.com>2014-10-27 12:53:08 -0700
committerGravatar Commit bot <commit-bot@chromium.org>2014-10-27 12:53:08 -0700
commitc6327a8f7e7e282c0b3a95049c75db7a8f92c693 (patch)
tree998c2fca0957d329d3c2c6796b70f85aee350ecc /src
parent96c60686eef6fc514feba6136f1b475f71dbf3ec (diff)
stuff
Diffstat (limited to 'src')
-rw-r--r--src/effects/SkTableColorFilter.cpp137
-rw-r--r--src/effects/gradients/SkGradientShader.cpp3
-rw-r--r--src/gpu/effects/GrTextureStripAtlas.cpp1
-rw-r--r--src/gpu/effects/GrTextureStripAtlas.h8
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.