////////////////////////////////////////////////////////////////////////////////////////////
-SkGradientShaderBase::SkGradientShaderBase(const Descriptor& desc)
+SkGradientShaderBase::SkGradientShaderBase(const Descriptor& desc, const SkMatrix& ptsToUnit)
: INHERITED(desc.fLocalMatrix)
+ , fPtsToUnit(ptsToUnit)
{
+ fPtsToUnit.getType(); // Precache so reads are threadsafe.
SkASSERT(desc.fCount > 1);
fGradFlags = SkToU8(desc.fGradFlags);
};
public:
- SkGradientShaderBase(const Descriptor& desc);
+ SkGradientShaderBase(const Descriptor& desc, const SkMatrix& ptsToUnit);
virtual ~SkGradientShaderBase();
// The cache is initialized on-demand when getCache16/32 is called.
virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
SK_TO_STRING_OVERRIDE()
- SkMatrix fPtsToUnit; // set by subclass
+ const SkMatrix fPtsToUnit;
TileMode fTileMode;
TileProc fTileProc;
int fColorCount;
#pragma optimize("", on)
#endif
-static void pts_to_unit_matrix(const SkPoint pts[2], SkMatrix* matrix) {
+static SkMatrix pts_to_unit_matrix(const SkPoint pts[2]) {
SkVector vec = pts[1] - pts[0];
SkScalar mag = vec.length();
SkScalar inv = mag ? SkScalarInvert(mag) : 0;
vec.scale(inv);
- matrix->setSinCos(-vec.fY, vec.fX, pts[0].fX, pts[0].fY);
- matrix->postTranslate(-pts[0].fX, -pts[0].fY);
- matrix->postScale(inv, inv);
+ SkMatrix matrix;
+ matrix.setSinCos(-vec.fY, vec.fX, pts[0].fX, pts[0].fY);
+ matrix.postTranslate(-pts[0].fX, -pts[0].fY);
+ matrix.postScale(inv, inv);
+ return matrix;
}
///////////////////////////////////////////////////////////////////////////////
SkLinearGradient::SkLinearGradient(const SkPoint pts[2], const Descriptor& desc)
- : SkGradientShaderBase(desc)
+ : SkGradientShaderBase(desc, pts_to_unit_matrix(pts))
, fStart(pts[0])
- , fEnd(pts[1])
-{
- pts_to_unit_matrix(pts, &fPtsToUnit);
+ , fEnd(pts[1]) {
}
SkFlattenable* SkLinearGradient::CreateProc(SkReadBuffer& buffer) {
#define kSQRT_TABLE_BITS 11
#define kSQRT_TABLE_SIZE (1 << kSQRT_TABLE_BITS)
+SK_COMPILE_ASSERT(sizeof(gSqrt8Table) == kSQRT_TABLE_SIZE, SqrtTableSizesMatch);
+
#if 0
#include <stdio.h>
return repeat_tileproc(x);
}
-void rad_to_unit_matrix(const SkPoint& center, SkScalar radius,
- SkMatrix* matrix) {
+SkMatrix rad_to_unit_matrix(const SkPoint& center, SkScalar radius) {
SkScalar inv = SkScalarInvert(radius);
- matrix->setTranslate(-center.fX, -center.fY);
- matrix->postScale(inv, inv);
+ SkMatrix matrix;
+ matrix.setTranslate(-center.fX, -center.fY);
+ matrix.postScale(inv, inv);
+ return matrix;
}
typedef void (* RadialShade16Proc)(SkScalar sfx, SkScalar sdx,
/////////////////////////////////////////////////////////////////////
SkRadialGradient::SkRadialGradient(const SkPoint& center, SkScalar radius, const Descriptor& desc)
- : SkGradientShaderBase(desc)
+ : SkGradientShaderBase(desc, rad_to_unit_matrix(center, radius))
, fCenter(center)
- , fRadius(radius)
-{
- // make sure our table is insync with our current #define for kSQRT_TABLE_SIZE
- SkASSERT(sizeof(gSqrt8Table) == kSQRT_TABLE_SIZE);
-
- rad_to_unit_matrix(center, radius, &fPtsToUnit);
+ , fRadius(radius) {
}
size_t SkRadialGradient::contextSize() const {
#include "SkSweepGradient.h"
+static SkMatrix translate(SkScalar dx, SkScalar dy) {
+ SkMatrix matrix;
+ matrix.setTranslate(dx, dy);
+ return matrix;
+}
+
SkSweepGradient::SkSweepGradient(SkScalar cx, SkScalar cy, const Descriptor& desc)
- : SkGradientShaderBase(desc)
+ : SkGradientShaderBase(desc, translate(-cx, -cy))
, fCenter(SkPoint::Make(cx, cy))
{
- fPtsToUnit.setTranslate(-cx, -cy);
-
// overwrite the tilemode to a canonical value (since sweep ignores it)
fTileMode = SkShader::kClamp_TileMode;
}
}
}
-void SkTwoPointConicalGradient::init() {
- fRec.init(fCenter1, fRadius1, fCenter2, fRadius2, fFlippedGrad);
- fPtsToUnit.reset();
-}
-
/////////////////////////////////////////////////////////////////////
SkTwoPointConicalGradient::SkTwoPointConicalGradient(
const SkPoint& start, SkScalar startRadius,
const SkPoint& end, SkScalar endRadius,
bool flippedGrad, const Descriptor& desc)
- : SkGradientShaderBase(desc)
+ : SkGradientShaderBase(desc, SkMatrix::I())
, fCenter1(start)
, fCenter2(end)
, fRadius1(startRadius)
{
// this is degenerate, and should be caught by our caller
SkASSERT(fCenter1 != fCenter2 || fRadius1 != fRadius2);
- this->init();
+ fRec.init(fCenter1, fRadius1, fCenter2, fRadius2, fFlippedGrad);
}
bool SkTwoPointConicalGradient::isOpaque() const {
class SkTwoPointConicalGradient : public SkGradientShaderBase {
TwoPtRadial fRec;
- void init();
-
public:
SkTwoPointConicalGradient(const SkPoint& start, SkScalar startRadius,
const SkPoint& end, SkScalar endRadius,
/////////////////////////////////////////////////////////////////////
+static SkMatrix pts_to_unit(const SkPoint& start, SkScalar diffRadius) {
+ SkScalar inv = diffRadius ? SkScalarInvert(diffRadius) : 0;
+ SkMatrix matrix;
+ matrix.setTranslate(-start.fX, -start.fY);
+ matrix.postScale(inv, inv);
+ return matrix;
+}
+
SkTwoPointRadialGradient::SkTwoPointRadialGradient(const SkPoint& start, SkScalar startRadius,
const SkPoint& end, SkScalar endRadius,
const Descriptor& desc)
- : SkGradientShaderBase(desc)
+ : SkGradientShaderBase(desc, pts_to_unit(start, endRadius - startRadius))
, fCenter1(start)
, fCenter2(end)
, fRadius1(startRadius)
, fRadius2(endRadius)
{
- init();
+ fDiff = fCenter1 - fCenter2;
+ fDiffRadius = fRadius2 - fRadius1;
+ // hack to avoid zero-divide for now
+ SkScalar inv = fDiffRadius ? SkScalarInvert(fDiffRadius) : 0;
+ fDiff.fX = SkScalarMul(fDiff.fX, inv);
+ fDiff.fY = SkScalarMul(fDiff.fY, inv);
+ fStartRadius = SkScalarMul(fRadius1, inv);
+ fSr2D2 = SkScalarSquare(fStartRadius);
+ fA = SkScalarSquare(fDiff.fX) + SkScalarSquare(fDiff.fY) - SK_Scalar1;
+ fOneOverTwoA = fA ? SkScalarInvert(fA * 2) : 0;
}
SkShader::BitmapType SkTwoPointRadialGradient::asABitmap(
buffer.writeScalar(fRadius2);
}
-void SkTwoPointRadialGradient::init() {
- fDiff = fCenter1 - fCenter2;
- fDiffRadius = fRadius2 - fRadius1;
- // hack to avoid zero-divide for now
- SkScalar inv = fDiffRadius ? SkScalarInvert(fDiffRadius) : 0;
- fDiff.fX = SkScalarMul(fDiff.fX, inv);
- fDiff.fY = SkScalarMul(fDiff.fY, inv);
- fStartRadius = SkScalarMul(fRadius1, inv);
- fSr2D2 = SkScalarSquare(fStartRadius);
- fA = SkScalarSquare(fDiff.fX) + SkScalarSquare(fDiff.fY) - SK_Scalar1;
- fOneOverTwoA = fA ? SkScalarInvert(fA * 2) : 0;
-
- fPtsToUnit.setTranslate(-fCenter1.fX, -fCenter1.fY);
- fPtsToUnit.postScale(inv, inv);
-}
-
/////////////////////////////////////////////////////////////////////
#if SK_SUPPORT_GPU
SkPoint fDiff;
SkScalar fStartRadius, fDiffRadius, fSr2D2, fA, fOneOverTwoA;
- void init();
-
friend class SkGradientShader;
typedef SkGradientShaderBase INHERITED;
};