#include "SkSweepGradient.h"
-SkSweepGradient::SkSweepGradient(SkScalar cx, SkScalar cy,
- const Descriptor& desc)
+SkSweepGradient::SkSweepGradient(SkScalar cx, SkScalar cy, const Descriptor& desc)
: SkGradientShaderBase(desc)
, fCenter(SkPoint::Make(cx, cy))
{
return kSweep_GradientType;
}
-SkSweepGradient::SkSweepGradient(SkFlattenableReadBuffer& buffer)
+SkSweepGradient::SkSweepGradient(SkReadBuffer& buffer)
: INHERITED(buffer),
fCenter(buffer.readPoint()) {
}
-void SkSweepGradient::flatten(SkFlattenableWriteBuffer& buffer) const {
+void SkSweepGradient::flatten(SkWriteBuffer& buffer) const {
this->INHERITED::flatten(buffer);
buffer.writePoint(fCenter);
}
+size_t SkSweepGradient::contextSize() const {
+ return sizeof(SweepGradientContext);
+}
+
+SkShader::Context* SkSweepGradient::onCreateContext(const ContextRec& rec, void* storage) const {
+ return SkNEW_PLACEMENT_ARGS(storage, SweepGradientContext, (*this, rec));
+}
+
+SkSweepGradient::SweepGradientContext::SweepGradientContext(
+ const SkSweepGradient& shader, const ContextRec& rec)
+ : INHERITED(shader, rec) {}
+
// returns angle in a circle [0..2PI) -> [0..255]
static unsigned SkATan2_255(float y, float x) {
// static const float g255Over2PI = 255 / (2 * SK_ScalarPI);
return ir;
}
-void SkSweepGradient::shadeSpan(int x, int y, SkPMColor* SK_RESTRICT dstC,
- int count) {
+void SkSweepGradient::SweepGradientContext::shadeSpan(int x, int y, SkPMColor* SK_RESTRICT dstC,
+ int count) {
SkMatrix::MapXYProc proc = fDstToIndexProc;
const SkMatrix& matrix = fDstToIndex;
- const SkPMColor* SK_RESTRICT cache = this->getCache32();
+ const SkPMColor* SK_RESTRICT cache = fCache->getCache32();
int toggle = init_dither_toggle(x, y);
SkPoint srcPt;
}
}
-void SkSweepGradient::shadeSpan16(int x, int y, uint16_t* SK_RESTRICT dstC,
- int count) {
+void SkSweepGradient::SweepGradientContext::shadeSpan16(int x, int y, uint16_t* SK_RESTRICT dstC,
+ int count) {
SkMatrix::MapXYProc proc = fDstToIndexProc;
const SkMatrix& matrix = fDstToIndex;
- const uint16_t* SK_RESTRICT cache = this->getCache16();
+ const uint16_t* SK_RESTRICT cache = fCache->getCache16();
int toggle = init_dither_toggle16(x, y);
SkPoint srcPt;
#if SK_SUPPORT_GPU
#include "GrTBackendEffectFactory.h"
+#include "gl/GrGLShaderBuilder.h"
+#include "SkGr.h"
class GrGLSweepGradient : public GrGLGradientEffect {
public:
virtual void emitCode(GrGLShaderBuilder*,
const GrDrawEffect&,
- EffectKey,
+ const GrEffectKey&,
const char* outputColor,
const char* inputColor,
const TransformedCoordsArray&,
const TextureSamplerArray&) SK_OVERRIDE;
- static EffectKey GenKey(const GrDrawEffect& drawEffect, const GrGLCaps&) {
- return GenBaseGradientKey(drawEffect);
+ static void GenKey(const GrDrawEffect& drawEffect, const GrGLCaps&, GrEffectKeyBuilder* b) {
+ b->add32(GenBaseGradientKey(drawEffect));
}
private:
class GrSweepGradient : public GrGradientEffect {
public:
- static GrEffectRef* Create(GrContext* ctx,
- const SkSweepGradient& shader,
- const SkMatrix& matrix) {
- AutoEffectUnref effect(SkNEW_ARGS(GrSweepGradient, (ctx, shader, matrix)));
- return CreateEffectRef(effect);
+ static GrEffect* Create(GrContext* ctx, const SkSweepGradient& shader, const SkMatrix& m) {
+ return SkNEW_ARGS(GrSweepGradient, (ctx, shader, m));
}
virtual ~GrSweepGradient() { }
GR_DEFINE_EFFECT_TEST(GrSweepGradient);
-GrEffectRef* GrSweepGradient::TestCreate(SkRandom* random,
+GrEffect* GrSweepGradient::TestCreate(SkRandom* random,
GrContext* context,
const GrDrawTargetCaps&,
GrTexture**) {
SkAutoTUnref<SkShader> shader(SkGradientShader::CreateSweep(center.fX, center.fY,
colors, stops, colorCount));
SkPaint paint;
- return shader->asNewEffect(context, paint);
+ GrEffect* effect;
+ GrColor paintColor;
+ SkAssertResult(shader->asNewEffect(context, paint, NULL, &paintColor, &effect));
+ return effect;
}
/////////////////////////////////////////////////////////////////////
void GrGLSweepGradient::emitCode(GrGLShaderBuilder* builder,
const GrDrawEffect&,
- EffectKey key,
+ const GrEffectKey& key,
const char* outputColor,
const char* inputColor,
const TransformedCoordsArray& coords,
const TextureSamplerArray& samplers) {
- this->emitUniforms(builder, key);
+ uint32_t baseKey = key.get32(0);
+ this->emitUniforms(builder, baseKey);
SkString coords2D = builder->ensureFSCoords2D(coords, 0);
+ const GrGLContextInfo ctxInfo = builder->ctxInfo();
SkString t;
- t.printf("atan(- %s.y, - %s.x) * 0.1591549430918 + 0.5", coords2D.c_str(), coords2D.c_str());
- this->emitColor(builder, t.c_str(), key,
- outputColor, inputColor, samplers);
+ // 0.1591549430918 is 1/(2*pi), used since atan returns values [-pi, pi]
+ // On Intel GPU there is an issue where it reads the second arguement to atan "- %s.x" as an int
+ // thus must us -1.0 * %s.x to work correctly
+ if (kIntel_GrGLVendor != ctxInfo.vendor()){
+ t.printf("atan(- %s.y, - %s.x) * 0.1591549430918 + 0.5",
+ coords2D.c_str(), coords2D.c_str());
+ } else {
+ t.printf("atan(- %s.y, -1.0 * %s.x) * 0.1591549430918 + 0.5",
+ coords2D.c_str(), coords2D.c_str());
+ }
+ this->emitColor(builder, t.c_str(), baseKey, outputColor, inputColor, samplers);
}
/////////////////////////////////////////////////////////////////////
-GrEffectRef* SkSweepGradient::asNewEffect(GrContext* context, const SkPaint&) const {
+bool SkSweepGradient::asNewEffect(GrContext* context, const SkPaint& paint,
+ const SkMatrix* localMatrix, GrColor* paintColor,
+ GrEffect** effect) const {
+
SkMatrix matrix;
if (!this->getLocalMatrix().invert(&matrix)) {
- return NULL;
+ return false;
+ }
+ if (localMatrix) {
+ SkMatrix inv;
+ if (!localMatrix->invert(&inv)) {
+ return false;
+ }
+ matrix.postConcat(inv);
}
matrix.postConcat(fPtsToUnit);
- return GrSweepGradient::Create(context, *this, matrix);
+
+ *effect = GrSweepGradient::Create(context, *this, matrix);
+ *paintColor = SkColor2GrColorJustAlpha(paint.getColor());
+
+ return true;
}
#else
-GrEffectRef* SkSweepGradient::asNewEffect(GrContext*, const SkPaint&) const {
+bool SkSweepGradient::asNewEffect(GrContext* context, const SkPaint& paint,
+ const SkMatrix* localMatrix, GrColor* paintColor,
+ GrEffect** effect) const {
SkDEBUGFAIL("Should not call in GPU-less build");
- return NULL;
+ return false;
}
#endif
-#ifdef SK_DEVELOPER
+#ifndef SK_IGNORE_TO_STRING
void SkSweepGradient::toString(SkString* str) const {
str->append("SkSweepGradient: (");