Reapply r5101 and r5102: Made gradient effects use GrTextureStripAtlas.
git-svn-id: http://skia.googlecode.com/svn/trunk@5192 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/src/effects/gradients/SkGradientShader.cpp b/src/effects/gradients/SkGradientShader.cpp
index 0bdbe54..be5b1b0 100644
--- a/src/effects/gradients/SkGradientShader.cpp
+++ b/src/effects/gradients/SkGradientShader.cpp
@@ -672,20 +672,38 @@
#if SK_SUPPORT_GPU
+#include "effects/GrTextureStripAtlas.h"
#include "SkGr.h"
GrGLGradientStage::GrGLGradientStage(const GrProgramStageFactory& factory)
- : INHERITED(factory) { }
+ : INHERITED(factory)
+ , fCachedYCoord(GR_ScalarMax)
+ , fFSYUni(GrGLUniformManager::kInvalidUniformHandle) { }
GrGLGradientStage::~GrGLGradientStage() { }
+void GrGLGradientStage::setupVariables(GrGLShaderBuilder* builder) {
+ fFSYUni = builder->addUniform(GrGLShaderBuilder::kFragment_ShaderType,
+ kFloat_GrSLType, "GradientYCoordFS");
+}
+
+void GrGLGradientStage::setData(const GrGLUniformManager& uman,
+ const GrCustomStage& stage,
+ const GrRenderTarget*,
+ int stageNum) {
+ GrScalar yCoord = static_cast<const GrGradientEffect&>(stage).getYCoord();
+ if (yCoord != fCachedYCoord) {
+ uman.set1f(fFSYUni, yCoord);
+ fCachedYCoord = yCoord;
+ }
+}
+
void GrGLGradientStage::emitColorLookup(GrGLShaderBuilder* builder,
const char* tName,
const char* outputColor,
const char* samplerName) {
- // Texture is effectively 1D so the y coordinate is 0.5, if we pack multiple
- // gradients into a texture, we could instead pick the appropriate row here
- builder->fSampleCoords.printf("vec2(%s, 0.5)", tName);
+ builder->fSampleCoords.printf("vec2(%s, %s)", tName,
+ builder->getUniformVariable(fFSYUni).c_str());
builder->fComplexCoord = true;
builder->emitDefaultFetch(outputColor, samplerName);
}
@@ -696,7 +714,7 @@
const SkGradientShaderBase& shader,
GrSamplerState* sampler)
: fTexture (NULL)
- , fUseTexture (false) {
+ , fUseTexture (true) {
// TODO: check for simple cases where we don't need a texture:
//GradientInfo info;
//shader.asAGradient(&info);
@@ -705,19 +723,38 @@
SkBitmap bitmap;
shader.getGradientTableBitmap(&bitmap);
- fTexture = GrLockCachedBitmapTexture(ctx, bitmap,
- sampler->textureParams());
- SkSafeRef(fTexture);
- fUseTexture = true;
-
- // Unlock immediately, this is not great, but we don't have a way of
- // knowing when else to unlock it currently, so it may get purged from
- // the cache, but it'll still be ref'd until it's no longer being used.
- GrUnlockCachedBitmapTexture(fTexture);
+ GrTextureStripAtlas::Desc desc;
+ desc.fWidth = bitmap.width();
+ desc.fHeight = 32;
+ desc.fRowHeight = bitmap.height();
+ desc.fContext = ctx;
+ desc.fConfig = SkBitmapConfig2GrPixelConfig(bitmap.config());
+ fAtlas = GrTextureStripAtlas::GetAtlas(desc);
+ GrAssert(NULL != fAtlas);
+
+ fRow = fAtlas->lockRow(bitmap);
+ if (-1 != fRow) {
+ fYCoord = fAtlas->getYOffset(fRow) + GR_ScalarHalf *
+ fAtlas->getVerticalScaleFactor();
+ fTexture = fAtlas->getTexture();
+ } else {
+ fTexture = GrLockCachedBitmapTexture(ctx, bitmap, sampler->textureParams());
+ SkSafeRef(fTexture);
+ fYCoord = GR_ScalarHalf;
+
+ // Unlock immediately, this is not great, but we don't have a way of
+ // knowing when else to unlock it currently, so it may get purged from
+ // the cache, but it'll still be ref'd until it's no longer being used.
+ GrUnlockCachedBitmapTexture(fTexture);
+ }
}
GrGradientEffect::~GrGradientEffect() {
- SkSafeUnref(fTexture);
+ if (this->useAtlas()) {
+ fAtlas->unlockRow(fRow);
+ } else {
+ SkSafeUnref(fTexture);
+ }
}
unsigned int GrGradientEffect::numTextures() const {