aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--gyp/gpu.gyp2
-rw-r--r--include/core/SkImageFilter.h3
-rw-r--r--include/gpu/GrCustomStage.h19
-rw-r--r--src/core/SkPaint.cpp2
-rw-r--r--src/effects/SkLightingImageFilter.cpp63
-rw-r--r--src/gpu/GrContext.cpp4
-rw-r--r--src/gpu/GrCustomStage.cpp21
-rw-r--r--src/gpu/SkGpuDevice.cpp29
-rw-r--r--src/gpu/effects/Gr1DKernelEffect.h12
-rw-r--r--src/gpu/effects/GrConvolutionEffect.cpp15
-rw-r--r--src/gpu/effects/GrConvolutionEffect.h3
-rw-r--r--src/gpu/effects/GrGradientEffects.cpp32
-rw-r--r--src/gpu/effects/GrGradientEffects.h35
-rw-r--r--src/gpu/effects/GrMorphologyEffect.cpp12
-rw-r--r--src/gpu/effects/GrMorphologyEffect.h2
-rw-r--r--src/gpu/effects/GrSingleTextureEffect.cpp29
-rw-r--r--src/gpu/effects/GrSingleTextureEffect.h28
-rw-r--r--src/gpu/gl/GrGLProgramStage.cpp1
-rw-r--r--src/gpu/gl/GrGLProgramStage.h1
-rw-r--r--src/gpu/gl/GrGpuGL.cpp15
-rw-r--r--src/gpu/gl/GrGpuGL.h1
-rw-r--r--src/gpu/gl/GrGpuGL_program.cpp2
-rw-r--r--src/gpu/gl/GrGpuGL_unittest.cpp27
23 files changed, 243 insertions, 115 deletions
diff --git a/gyp/gpu.gyp b/gyp/gpu.gyp
index cabd331488..4a708d8e38 100644
--- a/gyp/gpu.gyp
+++ b/gyp/gpu.gyp
@@ -293,6 +293,8 @@
'../src/gpu/effects/GrGradientEffects.h',
'../src/gpu/effects/GrMorphologyEffect.cpp',
'../src/gpu/effects/GrMorphologyEffect.h',
+ '../src/gpu/effects/GrSingleTextureEffect.cpp',
+ '../src/gpu/effects/GrSingleTextureEffect.h',
'../src/gpu/gl/GrGLCaps.cpp',
'../src/gpu/gl/GrGLCaps.h',
diff --git a/include/core/SkImageFilter.h b/include/core/SkImageFilter.h
index b7bf8bcfef..0915b90714 100644
--- a/include/core/SkImageFilter.h
+++ b/include/core/SkImageFilter.h
@@ -15,6 +15,7 @@ class SkDevice;
class SkMatrix;
struct SkPoint;
class GrCustomStage;
+class GrTexture;
/**
* Experimental.
@@ -86,7 +87,7 @@ public:
* in it. The caller assumes ownership of the stage, and it is up to the
* caller to unref it.
*/
- virtual bool asNewCustomStage(GrCustomStage** stage) const;
+ virtual bool asNewCustomStage(GrCustomStage** stage, GrTexture*) const;
/**
* Experimental.
diff --git a/include/gpu/GrCustomStage.h b/include/gpu/GrCustomStage.h
index fd01c9a767..9f5efd33fb 100644
--- a/include/gpu/GrCustomStage.h
+++ b/include/gpu/GrCustomStage.h
@@ -13,11 +13,17 @@
#include "GrProgramStageFactory.h"
class GrContext;
+class GrTexture;
/** Provides custom vertex shader, fragment shader, uniform data for a
particular stage of the Ganesh shading pipeline.
Subclasses must have a function that produces a human-readable name:
static const char* Name();
+ GrCustomStage objects *must* be immutable: after being constructed,
+ their fields may not change. (Immutability isn't actually required
+ until they've been used in a draw call, but supporting that would require
+ setters and getters that could fail, copy-on-write, or deep copying of these
+ objects when they're stored by a GrGLProgramStage.)
*/
class GrCustomStage : public GrRefCnt {
@@ -60,15 +66,22 @@ public:
To test for equivalence (that they will generate the same
shader code, but may have different uniforms), check equality
of the stageKey produced by the GrProgramStageFactory:
- a.getFactory().glStageKey(a) == b.getFactory().glStageKey(b). */
- virtual bool isEqual(const GrCustomStage&) const = 0;
+ a.getFactory().glStageKey(a) == b.getFactory().glStageKey(b).
+
+ The default implementation of this function returns true iff
+ the two stages have the same return value for numTextures() and
+ for texture() over all valid indicse.
+ */
+ virtual bool isEqual(const GrCustomStage&) const;
/** Human-meaningful string to identify this effect; may be embedded
in generated shader code. */
const char* name() const { return this->getFactory().name(); }
-private:
+ virtual unsigned int numTextures() const;
+ virtual GrTexture* texture(unsigned int index) const;
+private:
typedef GrRefCnt INHERITED;
};
diff --git a/src/core/SkPaint.cpp b/src/core/SkPaint.cpp
index ea2d1f636e..19abb4b085 100644
--- a/src/core/SkPaint.cpp
+++ b/src/core/SkPaint.cpp
@@ -2214,7 +2214,7 @@ bool SkImageFilter::onFilterBounds(const SkIRect& src, const SkMatrix& ctm,
return true;
}
-bool SkImageFilter::asNewCustomStage(GrCustomStage**) const {
+bool SkImageFilter::asNewCustomStage(GrCustomStage**, GrTexture*) const {
return false;
}
diff --git a/src/effects/SkLightingImageFilter.cpp b/src/effects/SkLightingImageFilter.cpp
index acfc73b789..8d1e8e7714 100644
--- a/src/effects/SkLightingImageFilter.cpp
+++ b/src/effects/SkLightingImageFilter.cpp
@@ -9,6 +9,7 @@
#include "SkBitmap.h"
#include "SkColorPriv.h"
#include "GrProgramStageFactory.h"
+#include "effects/GrSingleTextureEffect.h"
#include "gl/GrGLProgramStage.h"
#include "gl/GrGLSL.h"
#include "gl/GrGLTexture.h"
@@ -251,7 +252,7 @@ public:
SkDiffuseLightingImageFilter(SkLight* light, SkScalar surfaceScale, SkScalar kd);
SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkDiffuseLightingImageFilter)
- virtual bool asNewCustomStage(GrCustomStage** stage) const SK_OVERRIDE;
+ virtual bool asNewCustomStage(GrCustomStage** stage, GrTexture*) const SK_OVERRIDE;
SkScalar kd() const { return fKD; }
protected:
@@ -271,7 +272,7 @@ public:
SkSpecularLightingImageFilter(SkLight* light, SkScalar surfaceScale, SkScalar ks, SkScalar shininess);
SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkSpecularLightingImageFilter)
- virtual bool asNewCustomStage(GrCustomStage** stage) const SK_OVERRIDE;
+ virtual bool asNewCustomStage(GrCustomStage** stage, GrTexture*) const SK_OVERRIDE;
SkScalar ks() const { return fKS; }
SkScalar shininess() const { return fShininess; }
@@ -288,9 +289,9 @@ private:
};
-class GrLightingEffect : public GrCustomStage {
+class GrLightingEffect : public GrSingleTextureEffect {
public:
- GrLightingEffect(const SkLight* light, SkScalar surfaceScale);
+ GrLightingEffect(GrTexture* texture, const SkLight* light, SkScalar surfaceScale);
virtual ~GrLightingEffect();
virtual bool isEqual(const GrCustomStage&) const SK_OVERRIDE;
@@ -298,14 +299,17 @@ public:
const SkLight* light() const { return fLight; }
SkScalar surfaceScale() const { return fSurfaceScale; }
private:
- typedef GrCustomStage INHERITED;
+ typedef GrSingleTextureEffect INHERITED;
const SkLight* fLight;
SkScalar fSurfaceScale;
};
class GrDiffuseLightingEffect : public GrLightingEffect {
public:
- GrDiffuseLightingEffect(const SkLight* light, SkScalar surfaceScale, SkScalar kd);
+ GrDiffuseLightingEffect(GrTexture* texture,
+ const SkLight* light,
+ SkScalar surfaceScale,
+ SkScalar kd);
static const char* Name() { return "DiffuseLighting"; }
@@ -321,7 +325,11 @@ private:
class GrSpecularLightingEffect : public GrLightingEffect {
public:
- GrSpecularLightingEffect(const SkLight* light, SkScalar surfaceScale, SkScalar ks, SkScalar shininess);
+ GrSpecularLightingEffect(GrTexture* texture,
+ const SkLight* light,
+ SkScalar surfaceScale,
+ SkScalar ks,
+ SkScalar shininess);
static const char* Name() { return "SpecularLighting"; }
@@ -775,10 +783,11 @@ bool SkDiffuseLightingImageFilter::onFilterImage(Proxy*,
return true;
}
-bool SkDiffuseLightingImageFilter::asNewCustomStage(GrCustomStage** stage) const {
+bool SkDiffuseLightingImageFilter::asNewCustomStage(GrCustomStage** stage,
+ GrTexture* texture) const {
if (stage) {
SkScalar scale = SkScalarMul(surfaceScale(), SkIntToScalar(255));
- *stage = new GrDiffuseLightingEffect(light(), scale, kd());
+ *stage = new GrDiffuseLightingEffect(texture, light(), scale, kd());
}
return true;
}
@@ -838,10 +847,11 @@ bool SkSpecularLightingImageFilter::onFilterImage(Proxy*,
return true;
}
-bool SkSpecularLightingImageFilter::asNewCustomStage(GrCustomStage** stage) const {
+bool SkSpecularLightingImageFilter::asNewCustomStage(GrCustomStage** stage,
+ GrTexture* texture) const {
if (stage) {
SkScalar scale = SkScalarMul(surfaceScale(), SkIntToScalar(255));
- *stage = new GrSpecularLightingEffect(light(), scale, ks(), shininess());
+ *stage = new GrSpecularLightingEffect(texture, light(), scale, ks(), shininess());
}
return true;
}
@@ -869,7 +879,6 @@ public:
virtual void initUniforms(const GrGLInterface*, int programID) SK_OVERRIDE;
virtual void setData(const GrGLInterface*,
- const GrGLTexture&,
const GrCustomStage&,
int stageNum) SK_OVERRIDE;
@@ -894,7 +903,6 @@ public:
virtual void emitLightFunc(SkString* funcs) SK_OVERRIDE;
virtual void initUniforms(const GrGLInterface*, int programID) SK_OVERRIDE;
virtual void setData(const GrGLInterface*,
- const GrGLTexture&,
const GrCustomStage&,
int stageNum) SK_OVERRIDE;
@@ -916,7 +924,6 @@ public:
virtual void emitLightFunc(SkString* funcs) SK_OVERRIDE;
virtual void initUniforms(const GrGLInterface*, int programID) SK_OVERRIDE;
virtual void setData(const GrGLInterface*,
- const GrGLTexture&,
const GrCustomStage&,
int stageNum) SK_OVERRIDE;
@@ -931,8 +938,9 @@ private:
///////////////////////////////////////////////////////////////////////////////
-GrLightingEffect::GrLightingEffect(const SkLight* light, SkScalar surfaceScale)
- : fLight(light)
+GrLightingEffect::GrLightingEffect(GrTexture* texture, const SkLight* light, SkScalar surfaceScale)
+ : GrSingleTextureEffect(texture)
+ , fLight(light)
, fSurfaceScale(surfaceScale) {
fLight->ref();
}
@@ -944,14 +952,15 @@ GrLightingEffect::~GrLightingEffect() {
bool GrLightingEffect::isEqual(const GrCustomStage& sBase) const {
const GrLightingEffect& s =
static_cast<const GrLightingEffect&>(sBase);
- return fLight->isEqual(*s.fLight) &&
+ return INHERITED::isEqual(sBase) &&
+ fLight->isEqual(*s.fLight) &&
fSurfaceScale == s.fSurfaceScale;
}
///////////////////////////////////////////////////////////////////////////////
-GrDiffuseLightingEffect::GrDiffuseLightingEffect(const SkLight* light, SkScalar surfaceScale, SkScalar kd)
- : INHERITED(light, surfaceScale), fKD(kd) {
+GrDiffuseLightingEffect::GrDiffuseLightingEffect(GrTexture* texture, const SkLight* light, SkScalar surfaceScale, SkScalar kd)
+ : INHERITED(texture, light, surfaceScale), fKD(kd) {
}
const GrProgramStageFactory& GrDiffuseLightingEffect::getFactory() const {
@@ -1056,11 +1065,11 @@ GrGLProgramStage::StageKey GrGLLightingEffect::GenKey(
}
void GrGLLightingEffect::setData(const GrGLInterface* gl,
- const GrGLTexture& texture,
const GrCustomStage& data,
int stageNum) {
const GrLightingEffect& effect =
static_cast<const GrLightingEffect&>(data);
+ GrTexture& texture = *data.texture(0);
GR_GL_CALL(gl, Uniform2f(fImageIncrementLocation, 1.0f / texture.width(), 1.0f / texture.height()));
GR_GL_CALL(gl, Uniform1f(fSurfaceScaleLocation, effect.surfaceScale()));
fLight->setData(gl, effect.light());
@@ -1100,10 +1109,9 @@ void GrGLDiffuseLightingEffect::emitLightFunc(SkString* funcs) {
}
void GrGLDiffuseLightingEffect::setData(const GrGLInterface* gl,
- const GrGLTexture& texture,
const GrCustomStage& data,
int stageNum) {
- INHERITED::setData(gl, texture, data, stageNum);
+ INHERITED::setData(gl, data, stageNum);
const GrDiffuseLightingEffect& effect =
static_cast<const GrDiffuseLightingEffect&>(data);
GR_GL_CALL(gl, Uniform1f(fKDLocation, effect.kd()));
@@ -1111,8 +1119,8 @@ void GrGLDiffuseLightingEffect::setData(const GrGLInterface* gl,
///////////////////////////////////////////////////////////////////////////////
-GrSpecularLightingEffect::GrSpecularLightingEffect(const SkLight* light, SkScalar surfaceScale, SkScalar ks, SkScalar shininess)
- : INHERITED(light, surfaceScale),
+GrSpecularLightingEffect::GrSpecularLightingEffect(GrTexture* texture, const SkLight* light, SkScalar surfaceScale, SkScalar ks, SkScalar shininess)
+ : INHERITED(texture, light, surfaceScale),
fKS(ks),
fShininess(shininess) {
}
@@ -1170,10 +1178,9 @@ void GrGLSpecularLightingEffect::emitLightFunc(SkString* funcs) {
}
void GrGLSpecularLightingEffect::setData(const GrGLInterface* gl,
- const GrGLTexture& texture,
- const GrCustomStage& data,
- int stageNum) {
- INHERITED::setData(gl, texture, data, stageNum);
+ const GrCustomStage& data,
+ int stageNum) {
+ INHERITED::setData(gl, data, stageNum);
const GrSpecularLightingEffect& effect =
static_cast<const GrSpecularLightingEffect&>(data);
GR_GL_CALL(gl, Uniform1f(fKSLocation, effect.ks()));
diff --git a/src/gpu/GrContext.cpp b/src/gpu/GrContext.cpp
index 149359f83e..95e0ecac63 100644
--- a/src/gpu/GrContext.cpp
+++ b/src/gpu/GrContext.cpp
@@ -244,7 +244,7 @@ void apply_morphology(GrGpu* gpu,
sampleM.setIDiv(texture->width(), texture->height());
drawState->sampler(0)->reset(sampleM);
SkAutoTUnref<GrCustomStage> morph(
- SkNEW_ARGS(GrMorphologyEffect, (direction, radius, morphType)));
+ SkNEW_ARGS(GrMorphologyEffect, (texture, direction, radius, morphType)));
drawState->sampler(0)->setCustomStage(morph);
drawState->setTexture(0, texture);
gpu->drawSimpleRect(rect, NULL, 1 << 0);
@@ -264,7 +264,7 @@ void convolve_gaussian(GrGpu* gpu,
sampleM.setIDiv(texture->width(), texture->height());
drawState->sampler(0)->reset(sampleM);
SkAutoTUnref<GrConvolutionEffect> conv(SkNEW_ARGS(GrConvolutionEffect,
- (direction, radius)));
+ (texture, direction, radius)));
conv->setGaussianKernel(sigma);
drawState->sampler(0)->setCustomStage(conv);
drawState->setTexture(0, texture);
diff --git a/src/gpu/GrCustomStage.cpp b/src/gpu/GrCustomStage.cpp
index c0ec330339..66b78a6635 100644
--- a/src/gpu/GrCustomStage.cpp
+++ b/src/gpu/GrCustomStage.cpp
@@ -14,6 +14,7 @@ int32_t GrProgramStageFactory::fCurrStageClassID =
GrProgramStageFactory::kIllegalStageClassID;
GrCustomStage::GrCustomStage() {
+
}
GrCustomStage::~GrCustomStage() {
@@ -24,3 +25,23 @@ bool GrCustomStage::isOpaque(bool inputTextureIsOpaque) const {
return false;
}
+bool GrCustomStage::isEqual(const GrCustomStage& s) const {
+ if (this->numTextures() != s.numTextures()) {
+ return false;
+ }
+ for (unsigned int i = 0; i < this->numTextures(); ++i) {
+ if (this->texture(i) != s.texture(i)) {
+ return false;
+ }
+ }
+ return true;
+}
+
+unsigned int GrCustomStage::numTextures() const {
+ return 0;
+}
+
+GrTexture* GrCustomStage::texture(unsigned int index) const {
+ return NULL;
+}
+
diff --git a/src/gpu/SkGpuDevice.cpp b/src/gpu/SkGpuDevice.cpp
index 2a2bbcdc37..11543136a6 100644
--- a/src/gpu/SkGpuDevice.cpp
+++ b/src/gpu/SkGpuDevice.cpp
@@ -536,26 +536,36 @@ inline bool skPaint2GrPaintShader(SkGpuDevice* dev,
}
return false;
}
+
GrSamplerState* sampler = grPaint->textureSampler(kShaderTextureIdx);
+ GrTexture* texture = act->set(dev, bitmap, sampler);
+ if (NULL == texture) {
+ SkDebugf("Couldn't convert bitmap to texture.\n");
+ return false;
+ }
+ grPaint->setTexture(kShaderTextureIdx, texture);
+
switch (bmptype) {
case SkShader::kRadial_BitmapType:
- sampler->setCustomStage(SkNEW(GrRadialGradient))->unref();
+ sampler->setCustomStage(SkNEW_ARGS(GrRadialGradient, (texture)))->unref();
sampler->setFilter(GrSamplerState::kBilinear_Filter);
break;
case SkShader::kSweep_BitmapType:
- sampler->setCustomStage(SkNEW(GrSweepGradient))->unref();
+ sampler->setCustomStage(SkNEW_ARGS(GrSweepGradient, (texture)))->unref();
sampler->setFilter(GrSamplerState::kBilinear_Filter);
break;
case SkShader::kTwoPointRadial_BitmapType:
sampler->setCustomStage(SkNEW_ARGS(GrRadial2Gradient,
- (twoPointParams[0],
+ (texture,
+ twoPointParams[0],
twoPointParams[1],
twoPointParams[2] < 0)))->unref();
sampler->setFilter(GrSamplerState::kBilinear_Filter);
break;
case SkShader::kTwoPointConical_BitmapType:
sampler->setCustomStage(SkNEW_ARGS(GrConical2Gradient,
- (twoPointParams[0],
+ (texture,
+ twoPointParams[0],
twoPointParams[1],
twoPointParams[2])))->unref();
sampler->setFilter(GrSamplerState::kBilinear_Filter);
@@ -571,13 +581,6 @@ inline bool skPaint2GrPaintShader(SkGpuDevice* dev,
sampler->setWrapX(sk_tile_mode_to_grwrap(tileModes[0]));
sampler->setWrapY(sk_tile_mode_to_grwrap(tileModes[1]));
- GrTexture* texture = act->set(dev, bitmap, sampler);
- if (NULL == texture) {
- SkDebugf("Couldn't convert bitmap to texture.\n");
- return false;
- }
- grPaint->setTexture(kShaderTextureIdx, texture);
-
// since our texture coords will be in local space, we wack the texture
// matrix to map them back into 0...1 before we load it
SkMatrix localM;
@@ -1474,7 +1477,7 @@ static GrTexture* filter_texture(GrContext* context, GrTexture* texture,
desc.fConfig = kRGBA_8888_PM_GrPixelConfig;
GrCustomStage* stage;
- if (filter->asNewCustomStage(&stage)) {
+ if (filter->asNewCustomStage(&stage, texture)) {
GrAutoScratchTexture dst(context, desc);
apply_custom_stage(context, texture, dst.texture(), rect, stage);
texture = dst.detach();
@@ -1607,7 +1610,7 @@ bool SkGpuDevice::canHandleImageFilter(SkImageFilter* filter) {
SkSize size;
SkISize radius;
- if (!filter->asNewCustomStage(NULL) &&
+ if (!filter->asNewCustomStage(NULL, NULL) &&
!filter->asABlur(&size) &&
!filter->asADilate(&radius) &&
!filter->asAnErode(&radius)) {
diff --git a/src/gpu/effects/Gr1DKernelEffect.h b/src/gpu/effects/Gr1DKernelEffect.h
index b6e116fa96..9ef765268c 100644
--- a/src/gpu/effects/Gr1DKernelEffect.h
+++ b/src/gpu/effects/Gr1DKernelEffect.h
@@ -8,7 +8,7 @@
#ifndef Gr1DKernelEffect_DEFINED
#define Gr1DKernelEffect_DEFINED
-#include "GrCustomStage.h"
+#include "GrSingleTextureEffect.h"
/**
* Base class for 1D kernel effects. The kernel operates either in X or Y and
@@ -18,7 +18,7 @@
* read. Since the center pixel is also read, the total width is one larger than
* two times the radius.
*/
-class Gr1DKernelEffect : public GrCustomStage {
+class Gr1DKernelEffect : public GrSingleTextureEffect {
public:
enum Direction {
@@ -26,9 +26,11 @@ public:
kY_Direction,
};
- Gr1DKernelEffect(Direction direction,
+ Gr1DKernelEffect(GrTexture* texture,
+ Direction direction,
int radius)
- : fDirection(direction)
+ : GrSingleTextureEffect(texture)
+ , fDirection(direction)
, fRadius(radius) {}
virtual ~Gr1DKernelEffect() {};
@@ -44,7 +46,7 @@ private:
Direction fDirection;
int fRadius;
- typedef GrCustomStage INHERITED;
+ typedef GrSingleTextureEffect INHERITED;
};
#endif
diff --git a/src/gpu/effects/GrConvolutionEffect.cpp b/src/gpu/effects/GrConvolutionEffect.cpp
index 42dc2b49f1..4970d6270d 100644
--- a/src/gpu/effects/GrConvolutionEffect.cpp
+++ b/src/gpu/effects/GrConvolutionEffect.cpp
@@ -28,7 +28,6 @@ public:
virtual void initUniforms(const GrGLInterface*, int programID) SK_OVERRIDE;
virtual void setData(const GrGLInterface*,
- const GrGLTexture&,
const GrCustomStage&,
int stageNum) SK_OVERRIDE;
@@ -118,11 +117,11 @@ void GrGLConvolutionEffect::initUniforms(const GrGLInterface* gl,
}
void GrGLConvolutionEffect::setData(const GrGLInterface* gl,
- const GrGLTexture& texture,
const GrCustomStage& data,
int stageNum) {
const GrConvolutionEffect& conv =
static_cast<const GrConvolutionEffect&>(data);
+ GrTexture& texture = *data.texture(0);
// the code we generated was for a specific kernel radius
GrAssert(conv.radius() == fRadius);
float imageIncrement[2] = { 0 };
@@ -148,10 +147,11 @@ GrGLProgramStage::StageKey GrGLConvolutionEffect::GenKey(
///////////////////////////////////////////////////////////////////////////////
-GrConvolutionEffect::GrConvolutionEffect(Direction direction,
+GrConvolutionEffect::GrConvolutionEffect(GrTexture* texture,
+ Direction direction,
int radius,
const float* kernel)
- : Gr1DKernelEffect(direction, radius) {
+ : Gr1DKernelEffect(texture, direction, radius) {
GrAssert(radius <= kMaxKernelRadius);
int width = this->width();
if (NULL != kernel) {
@@ -171,9 +171,10 @@ const GrProgramStageFactory& GrConvolutionEffect::getFactory() const {
bool GrConvolutionEffect::isEqual(const GrCustomStage& sBase) const {
const GrConvolutionEffect& s =
static_cast<const GrConvolutionEffect&>(sBase);
- return (this->radius() == s.radius() &&
- this->direction() == s.direction() &&
- 0 == memcmp(fKernel, s.fKernel, this->width() * sizeof(float)));
+ return (INHERITED::isEqual(sBase) &&
+ this->radius() == s.radius() &&
+ this->direction() == s.direction() &&
+ 0 == memcmp(fKernel, s.fKernel, this->width() * sizeof(float)));
}
void GrConvolutionEffect::setGaussianKernel(float sigma) {
diff --git a/src/gpu/effects/GrConvolutionEffect.h b/src/gpu/effects/GrConvolutionEffect.h
index fd6883b430..58cad83b53 100644
--- a/src/gpu/effects/GrConvolutionEffect.h
+++ b/src/gpu/effects/GrConvolutionEffect.h
@@ -21,7 +21,8 @@ class GrConvolutionEffect : public Gr1DKernelEffect {
public:
- GrConvolutionEffect(Direction, int halfWidth, const float* kernel = NULL);
+ GrConvolutionEffect(GrTexture*, Direction,
+ int halfWidth, const float* kernel = NULL);
virtual ~GrConvolutionEffect();
void setKernel(const float* kernel) {
diff --git a/src/gpu/effects/GrGradientEffects.cpp b/src/gpu/effects/GrGradientEffects.cpp
index 604595692d..d4719b3a24 100644
--- a/src/gpu/effects/GrGradientEffects.cpp
+++ b/src/gpu/effects/GrGradientEffects.cpp
@@ -49,7 +49,8 @@ void GrGLRadialGradient::emitFS(GrGLShaderBuilder* state,
/////////////////////////////////////////////////////////////////////
-GrRadialGradient::GrRadialGradient() {
+GrRadialGradient::GrRadialGradient(GrTexture* texture)
+ : GrSingleTextureEffect(texture) {
}
@@ -63,7 +64,7 @@ const GrProgramStageFactory& GrRadialGradient::getFactory() const {
}
bool GrRadialGradient::isEqual(const GrCustomStage& sBase) const {
- return true;
+ return INHERITED::isEqual(sBase);
}
/////////////////////////////////////////////////////////////////////
@@ -86,7 +87,6 @@ public:
const char* samplerName) SK_OVERRIDE;
virtual void initUniforms(const GrGLInterface*, int programID) SK_OVERRIDE;
virtual void setData(const GrGLInterface*,
- const GrGLTexture&,
const GrCustomStage&,
int stageNum) SK_OVERRIDE;
@@ -257,7 +257,6 @@ void GrGLRadial2Gradient::initUniforms(const GrGLInterface* gl, int programID) {
}
void GrGLRadial2Gradient::setData(const GrGLInterface* gl,
- const GrGLTexture& texture,
const GrCustomStage& baseData,
int stageNum) {
const GrRadial2Gradient& data =
@@ -296,10 +295,12 @@ void GrGLRadial2Gradient::setData(const GrGLInterface* gl,
/////////////////////////////////////////////////////////////////////
-GrRadial2Gradient::GrRadial2Gradient(GrScalar center,
+GrRadial2Gradient::GrRadial2Gradient(GrTexture* texture,
+ GrScalar center,
GrScalar radius,
bool posRoot)
- : fCenterX1 (center)
+ : GrSingleTextureEffect(texture)
+ , fCenterX1 (center)
, fRadius0 (radius)
, fPosRoot (posRoot) {
@@ -316,7 +317,8 @@ const GrProgramStageFactory& GrRadial2Gradient::getFactory() const {
bool GrRadial2Gradient::isEqual(const GrCustomStage& sBase) const {
const GrRadial2Gradient& s = static_cast<const GrRadial2Gradient&>(sBase);
- return (this->fCenterX1 == s.fCenterX1 &&
+ return (INHERITED::isEqual(sBase) &&
+ this->fCenterX1 == s.fCenterX1 &&
this->fRadius0 == s.fRadius0 &&
this->fPosRoot == s.fPosRoot);
}
@@ -341,7 +343,6 @@ public:
const char* samplerName) SK_OVERRIDE;
virtual void initUniforms(const GrGLInterface*, int programID) SK_OVERRIDE;
virtual void setData(const GrGLInterface*,
- const GrGLTexture&,
const GrCustomStage&,
int stageNum) SK_OVERRIDE;
@@ -571,7 +572,6 @@ void GrGLConical2Gradient::initUniforms(const GrGLInterface* gl, int programID)
}
void GrGLConical2Gradient::setData(const GrGLInterface* gl,
- const GrGLTexture& texture,
const GrCustomStage& baseData,
int stageNum) {
const GrConical2Gradient& data =
@@ -612,10 +612,12 @@ void GrGLConical2Gradient::setData(const GrGLInterface* gl,
/////////////////////////////////////////////////////////////////////
-GrConical2Gradient::GrConical2Gradient(GrScalar center,
+GrConical2Gradient::GrConical2Gradient(GrTexture* texture,
+ GrScalar center,
GrScalar radius,
GrScalar diffRadius)
- : fCenterX1 (center)
+ : GrSingleTextureEffect (texture)
+ , fCenterX1 (center)
, fRadius0 (radius)
, fDiffRadius (diffRadius) {
@@ -632,7 +634,8 @@ const GrProgramStageFactory& GrConical2Gradient::getFactory() const {
bool GrConical2Gradient::isEqual(const GrCustomStage& sBase) const {
const GrConical2Gradient& s = static_cast<const GrConical2Gradient&>(sBase);
- return (this->fCenterX1 == s.fCenterX1 &&
+ return (INHERITED::isEqual(sBase) &&
+ this->fCenterX1 == s.fCenterX1 &&
this->fRadius0 == s.fRadius0 &&
this->fDiffRadius == s.fDiffRadius);
}
@@ -677,7 +680,8 @@ void GrGLSweepGradient::emitFS(GrGLShaderBuilder* state,
/////////////////////////////////////////////////////////////////////
-GrSweepGradient::GrSweepGradient() {
+GrSweepGradient::GrSweepGradient(GrTexture* texture)
+ : GrSingleTextureEffect(texture) {
}
@@ -690,6 +694,6 @@ const GrProgramStageFactory& GrSweepGradient::getFactory() const {
}
bool GrSweepGradient::isEqual(const GrCustomStage& sBase) const {
- return true;
+ return INHERITED::isEqual(sBase);
}
diff --git a/src/gpu/effects/GrGradientEffects.h b/src/gpu/effects/GrGradientEffects.h
index cf6827f251..37e4642eab 100644
--- a/src/gpu/effects/GrGradientEffects.h
+++ b/src/gpu/effects/GrGradientEffects.h
@@ -8,7 +8,7 @@
#ifndef GrGradientEffects_DEFINED
#define GrGradientEffects_DEFINED
-#include "GrCustomStage.h"
+#include "GrSingleTextureEffect.h"
#include "GrTypes.h"
#include "GrScalar.h"
@@ -37,11 +37,11 @@
class GrGLRadialGradient;
-class GrRadialGradient : public GrCustomStage {
+class GrRadialGradient : public GrSingleTextureEffect {
public:
- GrRadialGradient();
+ GrRadialGradient(GrTexture* texture);
virtual ~GrRadialGradient();
static const char* Name() { return "Radial Gradient"; }
@@ -52,24 +52,23 @@ public:
private:
- typedef GrCustomStage INHERITED;
+ typedef GrSingleTextureEffect INHERITED;
};
class GrGLRadial2Gradient;
-class GrRadial2Gradient : public GrCustomStage {
+class GrRadial2Gradient : public GrSingleTextureEffect {
public:
- GrRadial2Gradient(GrScalar center, GrScalar radius, bool posRoot);
+ GrRadial2Gradient(GrTexture* texture, GrScalar center, GrScalar radius, bool posRoot);
virtual ~GrRadial2Gradient();
static const char* Name() { return "Two-Point Radial Gradient"; }
virtual const GrProgramStageFactory& getFactory() const SK_OVERRIDE;
virtual bool isEqual(const GrCustomStage&) const SK_OVERRIDE;
- // The radial gradient parameters can collapse to a linear (instead
- // of quadratic) equation.
+ // The radial gradient parameters can collapse to a linear (instead of quadratic) equation.
bool isDegenerate() const { return GR_Scalar1 == fCenterX1; }
GrScalar center() const { return fCenterX1; }
GrScalar radius() const { return fRadius0; }
@@ -89,26 +88,24 @@ private:
// @}
- typedef GrCustomStage INHERITED;
+ typedef GrSingleTextureEffect INHERITED;
};
class GrGLConical2Gradient;
-class GrConical2Gradient : public GrCustomStage {
+class GrConical2Gradient : public GrSingleTextureEffect {
public:
- GrConical2Gradient(GrScalar center, GrScalar radius, GrScalar diffRadius);
+ GrConical2Gradient(GrTexture* texture, GrScalar center, GrScalar radius, GrScalar diffRadius);
virtual ~GrConical2Gradient();
static const char* Name() { return "Two-Point Conical Gradient"; }
virtual const GrProgramStageFactory& getFactory() const SK_OVERRIDE;
virtual bool isEqual(const GrCustomStage&) const SK_OVERRIDE;
- // The radial gradient parameters can collapse to a linear (instead
- // of quadratic) equation.
- bool isDegenerate() const { return SkScalarAbs(fDiffRadius) ==
- SkScalarAbs(fCenterX1); }
+ // The radial gradient parameters can collapse to a linear (instead of quadratic) equation.
+ bool isDegenerate() const { return SkScalarAbs(fDiffRadius) == SkScalarAbs(fCenterX1); }
GrScalar center() const { return fCenterX1; }
GrScalar diffRadius() const { return fDiffRadius; }
GrScalar radius() const { return fRadius0; }
@@ -127,16 +124,16 @@ private:
// @}
- typedef GrCustomStage INHERITED;
+ typedef GrSingleTextureEffect INHERITED;
};
class GrGLSweepGradient;
-class GrSweepGradient : public GrCustomStage {
+class GrSweepGradient : public GrSingleTextureEffect {
public:
- GrSweepGradient();
+ GrSweepGradient(GrTexture* texture);
virtual ~GrSweepGradient();
static const char* Name() { return "Sweep Gradient"; }
@@ -147,7 +144,7 @@ public:
protected:
- typedef GrCustomStage INHERITED;
+ typedef GrSingleTextureEffect INHERITED;
};
#endif
diff --git a/src/gpu/effects/GrMorphologyEffect.cpp b/src/gpu/effects/GrMorphologyEffect.cpp
index 43e870285f..3ea2cbd125 100644
--- a/src/gpu/effects/GrMorphologyEffect.cpp
+++ b/src/gpu/effects/GrMorphologyEffect.cpp
@@ -31,7 +31,6 @@ public:
virtual void initUniforms(const GrGLInterface*, int programID) SK_OVERRIDE;
virtual void setData(const GrGLInterface*,
- const GrGLTexture&,
const GrCustomStage&,
int stageNum) SK_OVERRIDE;
@@ -124,11 +123,12 @@ GrGLProgramStage::StageKey GrGLMorphologyEffect::GenKey(
}
void GrGLMorphologyEffect ::setData(const GrGLInterface* gl,
- const GrGLTexture& texture,
const GrCustomStage& data,
int stageNum) {
const Gr1DKernelEffect& kern =
static_cast<const Gr1DKernelEffect&>(data);
+ GrGLTexture& texture =
+ *static_cast<GrGLTexture*>(data.texture(0));
// the code we generated was for a specific kernel radius
GrAssert(kern.radius() == fRadius);
float imageIncrement[2] = { 0 };
@@ -147,10 +147,11 @@ void GrGLMorphologyEffect ::setData(const GrGLInterface* gl,
///////////////////////////////////////////////////////////////////////////////
-GrMorphologyEffect::GrMorphologyEffect(Direction direction,
+GrMorphologyEffect::GrMorphologyEffect(GrTexture* texture,
+ Direction direction,
int radius,
MorphologyType type)
- : Gr1DKernelEffect(direction, radius)
+ : Gr1DKernelEffect(texture, direction, radius)
, fType(type) {
}
@@ -164,7 +165,8 @@ const GrProgramStageFactory& GrMorphologyEffect::getFactory() const {
bool GrMorphologyEffect::isEqual(const GrCustomStage& sBase) const {
const GrMorphologyEffect& s =
static_cast<const GrMorphologyEffect&>(sBase);
- return (this->radius() == s.radius() &&
+ return (INHERITED::isEqual(sBase) &&
+ this->radius() == s.radius() &&
this->direction() == s.direction() &&
this->type() == s.type());
}
diff --git a/src/gpu/effects/GrMorphologyEffect.h b/src/gpu/effects/GrMorphologyEffect.h
index c784460819..c8bd2d51db 100644
--- a/src/gpu/effects/GrMorphologyEffect.h
+++ b/src/gpu/effects/GrMorphologyEffect.h
@@ -25,7 +25,7 @@ public:
typedef GrContext::MorphologyType MorphologyType;
- GrMorphologyEffect(Direction, int radius, MorphologyType);
+ GrMorphologyEffect(GrTexture*, Direction, int radius, MorphologyType);
virtual ~GrMorphologyEffect();
MorphologyType type() const { return fType; }
diff --git a/src/gpu/effects/GrSingleTextureEffect.cpp b/src/gpu/effects/GrSingleTextureEffect.cpp
new file mode 100644
index 0000000000..a373ebe4e1
--- /dev/null
+++ b/src/gpu/effects/GrSingleTextureEffect.cpp
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2012 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "effects/GrSingleTextureEffect.h"
+#include "GrTexture.h"
+
+GrSingleTextureEffect::GrSingleTextureEffect(GrTexture* texture)
+ : fTexture (texture) {
+ SkSafeRef(fTexture);
+}
+
+GrSingleTextureEffect::~GrSingleTextureEffect() {
+ SkSafeUnref(fTexture);
+}
+
+unsigned int GrSingleTextureEffect::numTextures() const {
+ return 1;
+}
+
+GrTexture* GrSingleTextureEffect::texture(unsigned int index) const {
+ GrAssert(0 == index);
+ return fTexture;
+}
+
+
diff --git a/src/gpu/effects/GrSingleTextureEffect.h b/src/gpu/effects/GrSingleTextureEffect.h
new file mode 100644
index 0000000000..9a6bd1cae3
--- /dev/null
+++ b/src/gpu/effects/GrSingleTextureEffect.h
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2012 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef GrSingleTextureEffect_DEFINED
+#define GrSingleTextureEffect_DEFINED
+
+#include "GrCustomStage.h"
+
+class GrSingleTextureEffect : public GrCustomStage {
+
+public:
+ GrSingleTextureEffect(GrTexture* texture);
+ virtual ~GrSingleTextureEffect();
+
+ virtual unsigned int numTextures() const SK_OVERRIDE;
+ virtual GrTexture* texture(unsigned int index) const SK_OVERRIDE;
+
+private:
+ GrTexture* fTexture;
+
+ typedef GrCustomStage INHERITED;
+};
+
+#endif
diff --git a/src/gpu/gl/GrGLProgramStage.cpp b/src/gpu/gl/GrGLProgramStage.cpp
index 487b46865f..b5e4f4068c 100644
--- a/src/gpu/gl/GrGLProgramStage.cpp
+++ b/src/gpu/gl/GrGLProgramStage.cpp
@@ -26,7 +26,6 @@ void GrGLProgramStage::initUniforms(const GrGLInterface*, int progID) {
}
void GrGLProgramStage::setData(const GrGLInterface*,
- const GrGLTexture&,
const GrCustomStage&,
int stageNum) {
}
diff --git a/src/gpu/gl/GrGLProgramStage.h b/src/gpu/gl/GrGLProgramStage.h
index fe3ed4b9b7..9cf2c1aa97 100644
--- a/src/gpu/gl/GrGLProgramStage.h
+++ b/src/gpu/gl/GrGLProgramStage.h
@@ -82,7 +82,6 @@ public:
a stage and uploads any uniform variables required by the shaders
created in emit*(). */
virtual void setData(const GrGLInterface* gl,
- const GrGLTexture& texture,
const GrCustomStage& stage,
int stageNum);
diff --git a/src/gpu/gl/GrGpuGL.cpp b/src/gpu/gl/GrGpuGL.cpp
index 7ebe9d7f06..edabb9c108 100644
--- a/src/gpu/gl/GrGpuGL.cpp
+++ b/src/gpu/gl/GrGpuGL.cpp
@@ -2140,6 +2140,21 @@ void GrGpuGL::flushBoundTextureAndParams(int stage) {
GrGLTexture* nextTexture =
static_cast<GrGLTexture*>(drawState->getTexture(stage));
+ // HACK - if we're using a new SingleTextureEffect, override
+ // the old texture pointer
+ const GrSamplerState& sampler = drawState->getSampler(stage);
+ GrCustomStage* customStage = sampler.getCustomStage();
+ if (customStage && customStage->numTextures()) {
+ nextTexture =
+ static_cast<GrGLTexture*>(customStage->texture(0));
+ }
+
+ flushBoundTextureAndParams(stage, nextTexture);
+}
+
+void GrGpuGL::flushBoundTextureAndParams(int stage, GrGLTexture* nextTexture) {
+ GrDrawState* drawState = this->drawState();
+
// true for now, but maybe not with GrEffect.
GrAssert(NULL != nextTexture);
// if we created a rt/tex and rendered to it without using a
diff --git a/src/gpu/gl/GrGpuGL.h b/src/gpu/gl/GrGpuGL.h
index 2d6aa68120..0871a57b7e 100644
--- a/src/gpu/gl/GrGpuGL.h
+++ b/src/gpu/gl/GrGpuGL.h
@@ -213,6 +213,7 @@ private:
// call to flushScissor must occur after all textures have been flushed via
// this function.
void flushBoundTextureAndParams(int stage);
+ void flushBoundTextureAndParams(int stage, GrGLTexture* nextTexture);
// sets the texture matrix and domain for the currently bound program
void flushTextureMatrixAndDomain(int stage);
diff --git a/src/gpu/gl/GrGpuGL_program.cpp b/src/gpu/gl/GrGpuGL_program.cpp
index 3a3d6386f0..a7187d548c 100644
--- a/src/gpu/gl/GrGpuGL_program.cpp
+++ b/src/gpu/gl/GrGpuGL_program.cpp
@@ -479,7 +479,7 @@ bool GrGpuGL::flushGraphicsState(DrawType type) {
static_cast<const GrGLTexture*>(
this->getDrawState().getTexture(s));
fProgramData->fCustomStage[s]->setData(
- this->glInterface(), *texture,
+ this->glInterface(),
*sampler.getCustomStage(), s);
}
}
diff --git a/src/gpu/gl/GrGpuGL_unittest.cpp b/src/gpu/gl/GrGpuGL_unittest.cpp
index 044d4777d9..004013a55a 100644
--- a/src/gpu/gl/GrGpuGL_unittest.cpp
+++ b/src/gpu/gl/GrGpuGL_unittest.cpp
@@ -77,7 +77,8 @@ GrCustomStage* create_random_effect(StageDesc* stageDesc,
stageDesc->fOptFlags |= StageDesc::kNoPerspective_OptFlagBit;
stageDesc->fInConfigFlags &= ~kMulByAlphaMask;
return SkNEW_ARGS(GrConvolutionEffect,
- (gKernelDirections[direction],
+ (NULL,
+ gKernelDirections[direction],
kernelRadius,
kernel));
}
@@ -88,7 +89,8 @@ GrCustomStage* create_random_effect(StageDesc* stageDesc,
stageDesc->fOptFlags |= StageDesc::kNoPerspective_OptFlagBit;
stageDesc->fInConfigFlags &= ~kMulByAlphaMask;
return SkNEW_ARGS(GrMorphologyEffect,
- (gKernelDirections[direction],
+ (NULL,
+ gKernelDirections[direction],
kernelRadius,
GrContext::kErode_MorphologyType));
}
@@ -99,12 +101,13 @@ GrCustomStage* create_random_effect(StageDesc* stageDesc,
stageDesc->fOptFlags |= StageDesc::kNoPerspective_OptFlagBit;
stageDesc->fInConfigFlags &= ~kMulByAlphaMask;
return SkNEW_ARGS(GrMorphologyEffect,
- (gKernelDirections[direction],
+ (NULL,
+ gKernelDirections[direction],
kernelRadius,
GrContext::kDilate_MorphologyType));
}
case kRadialGradient_EffectType: {
- return SkNEW(GrRadialGradient);
+ return SkNEW_ARGS(GrRadialGradient, (NULL));
}
case kRadial2Gradient_EffectType: {
float center;
@@ -113,10 +116,10 @@ GrCustomStage* create_random_effect(StageDesc* stageDesc,
} while (GR_Scalar1 == center);
float radius = random->nextF();
bool root = random_bool(random);
- return SkNEW_ARGS(GrRadial2Gradient, (center, radius, root));
+ return SkNEW_ARGS(GrRadial2Gradient, (NULL, center, radius, root));
}
case kSweepGradient_EffectType: {
- return SkNEW(GrSweepGradient);
+ return SkNEW_ARGS(GrSweepGradient, (NULL));
}
case kDiffuseDistant_EffectType: {
SkPoint3 direction = random_point3(random);
@@ -127,7 +130,7 @@ GrCustomStage* create_random_effect(StageDesc* stageDesc,
SkAutoTUnref<SkImageFilter> filter(SkLightingImageFilter::CreateDistantLitDiffuse(direction, lightColor, surfaceScale, kd));
// does not work with perspective or mul-by-alpha-mask
GrCustomStage* stage;
- bool ok = filter->asNewCustomStage(&stage);
+ bool ok = filter->asNewCustomStage(&stage, NULL);
SkASSERT(ok);
return stage;
}
@@ -139,7 +142,7 @@ GrCustomStage* create_random_effect(StageDesc* stageDesc,
SkAutoTUnref<SkImageFilter> filter(SkLightingImageFilter::CreatePointLitDiffuse(location, lightColor, surfaceScale, kd));
// does not work with perspective or mul-by-alpha-mask
GrCustomStage* stage;
- bool ok = filter->asNewCustomStage(&stage);
+ bool ok = filter->asNewCustomStage(&stage, NULL);
SkASSERT(ok);
return stage;
}
@@ -156,7 +159,7 @@ GrCustomStage* create_random_effect(StageDesc* stageDesc,
location, target, specularExponent, cutoffAngle, lightColor, surfaceScale, ks, shininess));
// does not work with perspective or mul-by-alpha-mask
GrCustomStage* stage;
- bool ok = filter->asNewCustomStage(&stage);
+ bool ok = filter->asNewCustomStage(&stage, NULL);
SkASSERT(ok);
return stage;
}
@@ -170,7 +173,7 @@ GrCustomStage* create_random_effect(StageDesc* stageDesc,
SkAutoTUnref<SkImageFilter> filter(SkLightingImageFilter::CreateDistantLitSpecular(direction, lightColor, surfaceScale, ks, shininess));
// does not work with perspective or mul-by-alpha-mask
GrCustomStage* stage;
- bool ok = filter->asNewCustomStage(&stage);
+ bool ok = filter->asNewCustomStage(&stage, NULL);
SkASSERT(ok);
return stage;
}
@@ -183,7 +186,7 @@ GrCustomStage* create_random_effect(StageDesc* stageDesc,
SkAutoTUnref<SkImageFilter> filter(SkLightingImageFilter::CreatePointLitSpecular(location, lightColor, surfaceScale, ks, shininess));
// does not work with perspective or mul-by-alpha-mask
GrCustomStage* stage;
- bool ok = filter->asNewCustomStage(&stage);
+ bool ok = filter->asNewCustomStage(&stage, NULL);
SkASSERT(ok);
return stage;
}
@@ -200,7 +203,7 @@ GrCustomStage* create_random_effect(StageDesc* stageDesc,
location, target, specularExponent, cutoffAngle, lightColor, surfaceScale, ks, shininess));
// does not work with perspective or mul-by-alpha-mask
GrCustomStage* stage;
- bool ok = filter->asNewCustomStage(&stage);
+ bool ok = filter->asNewCustomStage(&stage, NULL);
SkASSERT(ok);
return stage;
}