aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Florin Malita <fmalita@chromium.org>2017-03-23 17:04:54 -0400
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2017-03-23 23:06:07 +0000
commitda4545bfc58f8ec19df79f6ae75b7231477973d8 (patch)
tree210cc1abc6bbaedf81b5305109ec25dc9c37cb78
parent4dc6474b73ec4e5d6a1a0070e50d3d6766e4c94a (diff)
Extract 4f gradient interval functionality
... into structures usable outside Sk4fGradient classes. Change-Id: Ifffdbe8bafa4f027f2016ce71eefede6034dd3ae Reviewed-on: https://skia-review.googlesource.com/10060 Reviewed-by: Mike Reed <reed@google.com> Commit-Queue: Florin Malita <fmalita@chromium.org>
-rw-r--r--src/effects/gradients/Sk4fGradientBase.cpp279
-rw-r--r--src/effects/gradients/Sk4fGradientBase.h67
-rw-r--r--src/effects/gradients/Sk4fLinearGradient.cpp55
-rw-r--r--src/effects/gradients/Sk4fLinearGradient.h4
4 files changed, 205 insertions, 200 deletions
diff --git a/src/effects/gradients/Sk4fGradientBase.cpp b/src/effects/gradients/Sk4fGradientBase.cpp
index e234e9bc36..b385d8cd23 100644
--- a/src/effects/gradients/Sk4fGradientBase.cpp
+++ b/src/effects/gradients/Sk4fGradientBase.cpp
@@ -95,11 +95,30 @@ private:
const int fAdvance;
};
+void addMirrorIntervals(const SkColor colors[],
+ const SkScalar pos[], int count,
+ const Sk4f& componentScale,
+ bool premulColors, bool reverse,
+ Sk4fGradientIntervalBuffer::BufferType* buffer) {
+ const IntervalIterator iter(colors, pos, count, reverse);
+ iter.iterate([&] (SkColor c0, SkColor c1, SkScalar p0, SkScalar p1) {
+ SkASSERT(buffer->empty() || buffer->back().fP1 == 2 - p0);
+
+ const auto mirror_p0 = 2 - p0;
+ const auto mirror_p1 = 2 - p1;
+ // mirror_p1 & mirror_p1 may collapse for very small values - recheck to avoid
+ // triggering Interval asserts.
+ if (mirror_p0 != mirror_p1) {
+ buffer->emplace_back(pack_color(c0, premulColors, componentScale), mirror_p0,
+ pack_color(c1, premulColors, componentScale), mirror_p1);
+ }
+ });
+}
+
} // anonymous namespace
-SkGradientShaderBase::GradientShaderBase4fContext::
-Interval::Interval(const Sk4f& c0, SkScalar p0,
- const Sk4f& c1, SkScalar p1)
+Sk4fGradientInterval::Sk4fGradientInterval(const Sk4f& c0, SkScalar p0,
+ const Sk4f& c1, SkScalar p1)
: fP0(p0)
, fP1(p1)
, fZeroRamp((c0 == c1).allTrue()) {
@@ -117,39 +136,9 @@ Interval::Interval(const Sk4f& c0, SkScalar p0,
dc.store(&fDc.fVec);
}
-SkGradientShaderBase::
-GradientShaderBase4fContext::GradientShaderBase4fContext(const SkGradientShaderBase& shader,
- const ContextRec& rec)
- : INHERITED(shader, rec)
- , fFlags(this->INHERITED::getFlags())
-#ifdef SK_SUPPORT_LEGACY_GRADIENT_DITHERING
- , fDither(true)
-#else
- , fDither(rec.fPaint->isDither())
-#endif
-{
- const SkMatrix& inverse = this->getTotalInverse();
- fDstToPos.setConcat(shader.fPtsToUnit, inverse);
- fDstToPosProc = fDstToPos.getMapXYProc();
- fDstToPosClass = static_cast<uint8_t>(INHERITED::ComputeMatrixClass(fDstToPos));
-
- if (shader.fColorsAreOpaque && this->getPaintAlpha() == SK_AlphaOPAQUE) {
- fFlags |= kOpaqueAlpha_Flag;
- }
-
- fColorsArePremul =
- (shader.fGradFlags & SkGradientShader::kInterpolateColorsInPremul_Flag)
- || shader.fColorsAreOpaque;
-}
-
-bool SkGradientShaderBase::
-GradientShaderBase4fContext::isValid() const {
- return fDstToPos.isFinite();
-}
-
-void SkGradientShaderBase::
-GradientShaderBase4fContext::buildIntervals(const SkGradientShaderBase& shader,
- const ContextRec& rec, bool reverse) {
+void Sk4fGradientIntervalBuffer::init(const SkColor colors[], const SkScalar pos[], int count,
+ SkShader::TileMode tileMode, bool premulColors,
+ SkScalar alpha, bool reverse) {
// The main job here is to build a specialized interval list: a different
// representation of the color stops data, optimized for efficient scan line
// access during shading.
@@ -191,77 +180,131 @@ GradientShaderBase4fContext::buildIntervals(const SkGradientShaderBase& shader,
//
// TODO: investigate collapsing intervals << 1px.
- SkASSERT(shader.fColorCount > 0);
- SkASSERT(shader.fOrigColors);
+ SkASSERT(count > 0);
+ SkASSERT(colors);
- const float paintAlpha = rec.fPaint->getAlpha() * (1.0f / 255);
- const Sk4f componentScale = fColorsArePremul
- ? Sk4f(paintAlpha)
- : Sk4f(1.0f, 1.0f, 1.0f, paintAlpha);
- const int first_index = reverse ? shader.fColorCount - 1 : 0;
- const int last_index = shader.fColorCount - 1 - first_index;
+ fIntervals.reset();
+
+ const Sk4f componentScale = premulColors
+ ? Sk4f(alpha)
+ : Sk4f(1.0f, 1.0f, 1.0f, alpha);
+ const int first_index = reverse ? count - 1 : 0;
+ const int last_index = count - 1 - first_index;
const SkScalar first_pos = reverse ? SK_Scalar1 : 0;
const SkScalar last_pos = SK_Scalar1 - first_pos;
- if (shader.fTileMode == SkShader::kClamp_TileMode) {
+ if (tileMode == SkShader::kClamp_TileMode) {
// synthetic edge interval: -/+inf .. P0
- const Sk4f clamp_color = pack_color(shader.fOrigColors[first_index],
- fColorsArePremul, componentScale);
+ const Sk4f clamp_color = pack_color(colors[first_index],
+ premulColors, componentScale);
const SkScalar clamp_pos = reverse ? SK_ScalarInfinity : SK_ScalarNegativeInfinity;
fIntervals.emplace_back(clamp_color, clamp_pos,
clamp_color, first_pos);
- } else if (shader.fTileMode == SkShader::kMirror_TileMode && reverse) {
+ } else if (tileMode == SkShader::kMirror_TileMode && reverse) {
// synthetic mirror intervals injected before main intervals: (2 .. 1]
- addMirrorIntervals(shader, componentScale, false);
+ addMirrorIntervals(colors, pos, count, componentScale, premulColors, false, &fIntervals);
}
- const IntervalIterator iter(shader.fOrigColors,
- shader.fOrigPos,
- shader.fColorCount,
- reverse);
- iter.iterate([this, &componentScale] (SkColor c0, SkColor c1, SkScalar p0, SkScalar p1) {
+ const IntervalIterator iter(colors, pos, count, reverse);
+ iter.iterate([&] (SkColor c0, SkColor c1, SkScalar p0, SkScalar p1) {
SkASSERT(fIntervals.empty() || fIntervals.back().fP1 == p0);
- fIntervals.emplace_back(pack_color(c0, fColorsArePremul, componentScale),
- p0,
- pack_color(c1, fColorsArePremul, componentScale),
- p1);
+ fIntervals.emplace_back(pack_color(c0, premulColors, componentScale), p0,
+ pack_color(c1, premulColors, componentScale), p1);
});
- if (shader.fTileMode == SkShader::kClamp_TileMode) {
+ if (tileMode == SkShader::kClamp_TileMode) {
// synthetic edge interval: Pn .. +/-inf
- const Sk4f clamp_color = pack_color(shader.fOrigColors[last_index],
- fColorsArePremul, componentScale);
+ const Sk4f clamp_color = pack_color(colors[last_index], premulColors, componentScale);
const SkScalar clamp_pos = reverse ? SK_ScalarNegativeInfinity : SK_ScalarInfinity;
fIntervals.emplace_back(clamp_color, last_pos,
clamp_color, clamp_pos);
- } else if (shader.fTileMode == SkShader::kMirror_TileMode && !reverse) {
+ } else if (tileMode == SkShader::kMirror_TileMode && !reverse) {
// synthetic mirror intervals injected after main intervals: [1 .. 2)
- addMirrorIntervals(shader, componentScale, true);
+ addMirrorIntervals(colors, pos, count, componentScale, premulColors, true, &fIntervals);
}
}
-void SkGradientShaderBase::
-GradientShaderBase4fContext::addMirrorIntervals(const SkGradientShaderBase& shader,
- const Sk4f& componentScale, bool reverse) {
- const IntervalIterator iter(shader.fOrigColors,
- shader.fOrigPos,
- shader.fColorCount,
- reverse);
- iter.iterate([this, &componentScale] (SkColor c0, SkColor c1, SkScalar p0, SkScalar p1) {
- SkASSERT(fIntervals.empty() || fIntervals.back().fP1 == 2 - p0);
+const Sk4fGradientInterval* Sk4fGradientIntervalBuffer::find(SkScalar t) const {
+ // Binary search.
+ const auto* i0 = fIntervals.begin();
+ const auto* i1 = fIntervals.end() - 1;
- const auto mirror_p0 = 2 - p0;
- const auto mirror_p1 = 2 - p1;
- // mirror_p1 & mirror_p1 may collapse for very small values - recheck to avoid
- // triggering Interval asserts.
- if (mirror_p0 != mirror_p1) {
- fIntervals.emplace_back(pack_color(c0, fColorsArePremul, componentScale),
- mirror_p0,
- pack_color(c1, fColorsArePremul, componentScale),
- mirror_p1);
+ while (i0 != i1) {
+ SkASSERT(i0 < i1);
+ SkASSERT(t >= i0->fP0 && t <= i1->fP1);
+
+ const auto* i = i0 + ((i1 - i0) >> 1);
+
+ if (t > i->fP1) {
+ i0 = i + 1;
+ } else {
+ i1 = i;
}
- });
+ }
+
+ SkASSERT(i0->contains(t));
+ return i0;
+}
+
+const Sk4fGradientInterval* Sk4fGradientIntervalBuffer::findNext(
+ SkScalar t, const Sk4fGradientInterval* prev, bool increasing) const {
+
+ SkASSERT(!prev->contains(t));
+ SkASSERT(prev >= fIntervals.begin() && prev < fIntervals.end());
+ SkASSERT(t >= fIntervals.front().fP0 && t <= fIntervals.back().fP1);
+
+ const auto* i = prev;
+
+ // Use the |increasing| signal to figure which direction we should search for
+ // the next interval, then perform a linear search.
+ if (increasing) {
+ do {
+ i += 1;
+ if (i >= fIntervals.end()) {
+ i = fIntervals.begin();
+ }
+ } while (!i->contains(t));
+ } else {
+ do {
+ i -= 1;
+ if (i < fIntervals.begin()) {
+ i = fIntervals.end() - 1;
+ }
+ } while (!i->contains(t));
+ }
+
+ return i;
+}
+
+SkGradientShaderBase::
+GradientShaderBase4fContext::GradientShaderBase4fContext(const SkGradientShaderBase& shader,
+ const ContextRec& rec)
+ : INHERITED(shader, rec)
+ , fFlags(this->INHERITED::getFlags())
+#ifdef SK_SUPPORT_LEGACY_GRADIENT_DITHERING
+ , fDither(true)
+#else
+ , fDither(rec.fPaint->isDither())
+#endif
+{
+ const SkMatrix& inverse = this->getTotalInverse();
+ fDstToPos.setConcat(shader.fPtsToUnit, inverse);
+ fDstToPosProc = fDstToPos.getMapXYProc();
+ fDstToPosClass = static_cast<uint8_t>(INHERITED::ComputeMatrixClass(fDstToPos));
+
+ if (shader.fColorsAreOpaque && this->getPaintAlpha() == SK_AlphaOPAQUE) {
+ fFlags |= kOpaqueAlpha_Flag;
+ }
+
+ fColorsArePremul =
+ (shader.fGradFlags & SkGradientShader::kInterpolateColorsInPremul_Flag)
+ || shader.fColorsAreOpaque;
+}
+
+bool SkGradientShaderBase::
+GradientShaderBase4fContext::isValid() const {
+ return fDstToPos.isFinite();
}
void SkGradientShaderBase::
@@ -335,10 +378,8 @@ template<DstType dstType, ApplyPremul premul, SkShader::TileMode tileMode>
class SkGradientShaderBase::GradientShaderBase4fContext::TSampler {
public:
TSampler(const GradientShaderBase4fContext& ctx)
- : fFirstInterval(ctx.fIntervals.begin())
- , fLastInterval(ctx.fIntervals.end() - 1)
+ : fCtx(ctx)
, fInterval(nullptr) {
- SkASSERT(fLastInterval >= fFirstInterval);
switch (tileMode) {
case kClamp_TileMode:
fLargestIntervalValue = SK_ScalarInfinity;
@@ -358,10 +399,10 @@ public:
if (!fInterval) {
// Very first sample => locate the initial interval.
// TODO: maybe do this in ctor to remove a branch?
- fInterval = this->findFirstInterval(tiled_t);
+ fInterval = fCtx.fIntervals.find(tiled_t);
this->loadIntervalData(fInterval);
} else if (!fInterval->contains(tiled_t)) {
- fInterval = this->findNextInterval(t, tiled_t);
+ fInterval = fCtx.fIntervals.findNext(tiled_t, fInterval, t >= fPrevT);
this->loadIntervalData(fInterval);
}
@@ -395,65 +436,15 @@ private:
return fCc + fDc * (t - fInterval->fP0);
}
- const Interval* findFirstInterval(SkScalar t) const {
- // Binary search.
- const Interval* i0 = fFirstInterval;
- const Interval* i1 = fLastInterval;
-
- while (i0 != i1) {
- SkASSERT(i0 < i1);
- SkASSERT(t >= i0->fP0 && t <= i1->fP1);
-
- const Interval* i = i0 + ((i1 - i0) >> 1);
-
- if (t > i->fP1) {
- i0 = i + 1;
- } else {
- i1 = i;
- }
- }
-
- SkASSERT(i0->contains(t));
- return i0;
- }
-
- const Interval* findNextInterval(SkScalar t, SkScalar tiled_t) const {
- SkASSERT(!fInterval->contains(tiled_t));
- SkASSERT(tiled_t >= fFirstInterval->fP0 && tiled_t <= fLastInterval->fP1);
-
- const Interval* i = fInterval;
-
- // Use the t vs. prev_t signal to figure which direction we should search for
- // the next interval, then perform a linear search.
- if (t >= fPrevT) {
- do {
- i += 1;
- if (i > fLastInterval) {
- i = fFirstInterval;
- }
- } while (!i->contains(tiled_t));
- } else {
- do {
- i -= 1;
- if (i < fFirstInterval) {
- i = fLastInterval;
- }
- } while (!i->contains(tiled_t));
- }
-
- return i;
- }
-
- void loadIntervalData(const Interval* i) {
+ void loadIntervalData(const Sk4fGradientInterval* i) {
fCc = DstTraits<dstType, premul>::load(i->fC0);
fDc = DstTraits<dstType, premul>::load(i->fDc);
}
- const Interval* fFirstInterval;
- const Interval* fLastInterval;
- const Interval* fInterval;
- SkScalar fPrevT;
- SkScalar fLargestIntervalValue;
- Sk4f fCc;
- Sk4f fDc;
+ const GradientShaderBase4fContext& fCtx;
+ const Sk4fGradientInterval* fInterval;
+ SkScalar fPrevT;
+ SkScalar fLargestIntervalValue;
+ Sk4f fCc;
+ Sk4f fDc;
};
diff --git a/src/effects/gradients/Sk4fGradientBase.h b/src/effects/gradients/Sk4fGradientBase.h
index 6d0c3b96ff..2826f9e7b7 100644
--- a/src/effects/gradients/Sk4fGradientBase.h
+++ b/src/effects/gradients/Sk4fGradientBase.h
@@ -17,6 +17,39 @@
#include "SkShader.h"
#include "SkTArray.h"
+struct Sk4fGradientInterval {
+ Sk4fGradientInterval(const Sk4f& c0, SkScalar p0,
+ const Sk4f& c1, SkScalar p1);
+
+ bool contains(SkScalar t) const {
+ // True if t is in [p0,p1]. Note: this helper assumes a
+ // natural/increasing interval - so it's not usable in Sk4fLinearGradient.
+ SkASSERT(fP0 < fP1);
+ return t >= fP0 && t <= fP1;
+ }
+
+ SkPM4f fC0, fDc;
+ SkScalar fP0, fP1;
+ bool fZeroRamp;
+};
+
+class Sk4fGradientIntervalBuffer {
+public:
+ void init(const SkColor colors[], const SkScalar pos[], int count,
+ SkShader::TileMode tileMode, bool premulColors, SkScalar alpha, bool reverse);
+
+ const Sk4fGradientInterval* find(SkScalar t) const;
+ const Sk4fGradientInterval* findNext(SkScalar t, const Sk4fGradientInterval* prev,
+ bool increasing) const;
+
+ using BufferType = SkSTArray<8, Sk4fGradientInterval, true>;
+
+ const BufferType* operator->() const { return &fIntervals; }
+
+private:
+ BufferType fIntervals;
+};
+
class SkGradientShaderBase::
GradientShaderBase4fContext : public SkShader::Context {
public:
@@ -31,35 +64,15 @@ public:
bool isValid() const;
protected:
- struct Interval {
- Interval(const Sk4f& c0, SkScalar p0,
- const Sk4f& c1, SkScalar p1);
-
- bool isZeroRamp() const { return fZeroRamp; }
-
- bool contains(SkScalar p) const {
- // True if p is in [p0,p1]. Note: this helper assumes a
- // natural/increasing interval - so it's not usable in Sk4fLinearGradient.
- SkASSERT(fP0 < fP1);
- return p >= fP0 && p <= fP1;
- }
-
- SkPM4f fC0, fDc;
- SkScalar fP0, fP1;
- bool fZeroRamp;
- };
-
virtual void mapTs(int x, int y, SkScalar ts[], int count) const = 0;
- void buildIntervals(const SkGradientShaderBase&, const ContextRec&, bool reverse);
-
- SkSTArray<8, Interval, true> fIntervals;
- SkMatrix fDstToPos;
- SkMatrix::MapXYProc fDstToPosProc;
- uint8_t fDstToPosClass;
- uint8_t fFlags;
- bool fDither;
- bool fColorsArePremul;
+ Sk4fGradientIntervalBuffer fIntervals;
+ SkMatrix fDstToPos;
+ SkMatrix::MapXYProc fDstToPosProc;
+ uint8_t fDstToPosClass;
+ uint8_t fFlags;
+ bool fDither;
+ bool fColorsArePremul;
private:
using INHERITED = SkShader::Context;
diff --git a/src/effects/gradients/Sk4fLinearGradient.cpp b/src/effects/gradients/Sk4fLinearGradient.cpp
index 354c941a86..1256b8f6da 100644
--- a/src/effects/gradients/Sk4fLinearGradient.cpp
+++ b/src/effects/gradients/Sk4fLinearGradient.cpp
@@ -129,40 +129,41 @@ LinearGradient4fContext::LinearGradient4fContext(const SkLinearGradient& shader,
// Our fast path expects interval points to be monotonically increasing in x.
const bool reverseIntervals = this->isFast() && std::signbit(fDstToPos.getScaleX());
- this->buildIntervals(shader, rec, reverseIntervals);
+ fIntervals.init(shader.fOrigColors, shader.fOrigPos, shader.fColorCount, shader.fTileMode,
+ fColorsArePremul, rec.fPaint->getAlpha() * (1.0f / 255), reverseIntervals);
- SkASSERT(fIntervals.count() > 0);
- fCachedInterval = fIntervals.begin();
+ SkASSERT(fIntervals->count() > 0);
+ fCachedInterval = fIntervals->begin();
}
-const SkGradientShaderBase::GradientShaderBase4fContext::Interval*
+const Sk4fGradientInterval*
SkLinearGradient::LinearGradient4fContext::findInterval(SkScalar fx) const {
- SkASSERT(in_range(fx, fIntervals.front().fP0, fIntervals.back().fP1));
+ SkASSERT(in_range(fx, fIntervals->front().fP0, fIntervals->back().fP1));
if (1) {
// Linear search, using the last scanline interval as a starting point.
- SkASSERT(fCachedInterval >= fIntervals.begin());
- SkASSERT(fCachedInterval < fIntervals.end());
+ SkASSERT(fCachedInterval >= fIntervals->begin());
+ SkASSERT(fCachedInterval < fIntervals->end());
const int search_dir = fDstToPos.getScaleX() >= 0 ? 1 : -1;
while (!in_range(fx, fCachedInterval->fP0, fCachedInterval->fP1)) {
fCachedInterval += search_dir;
- if (fCachedInterval >= fIntervals.end()) {
- fCachedInterval = fIntervals.begin();
- } else if (fCachedInterval < fIntervals.begin()) {
- fCachedInterval = fIntervals.end() - 1;
+ if (fCachedInterval >= fIntervals->end()) {
+ fCachedInterval = fIntervals->begin();
+ } else if (fCachedInterval < fIntervals->begin()) {
+ fCachedInterval = fIntervals->end() - 1;
}
}
return fCachedInterval;
} else {
// Binary search. Seems less effective than linear + caching.
- const Interval* i0 = fIntervals.begin();
- const Interval* i1 = fIntervals.end() - 1;
+ const auto* i0 = fIntervals->begin();
+ const auto* i1 = fIntervals->end() - 1;
while (i0 != i1) {
SkASSERT(i0 < i1);
SkASSERT(in_range(fx, i0->fP0, i1->fP1));
- const Interval* i = i0 + ((i1 - i0) >> 1);
+ const auto* i = i0 + ((i1 - i0) >> 1);
if (in_range(fx, i0->fP0, i->fP1)) {
i1 = i;
@@ -251,8 +252,8 @@ LinearGradient4fContext::shadeSpanInternal(int x, int y,
&pt);
const SkScalar fx = pinFx<tileMode>(pt.x());
const SkScalar dx = fDstToPos.getScaleX();
- LinearIntervalProcessor<dstType, premul, tileMode> proc(fIntervals.begin(),
- fIntervals.end() - 1,
+ LinearIntervalProcessor<dstType, premul, tileMode> proc(fIntervals->begin(),
+ fIntervals->end() - 1,
this->findInterval(fx),
fx,
dx,
@@ -289,9 +290,9 @@ template<DstType dstType, ApplyPremul premul, SkShader::TileMode tileMode>
class SkLinearGradient::
LinearGradient4fContext::LinearIntervalProcessor {
public:
- LinearIntervalProcessor(const Interval* firstInterval,
- const Interval* lastInterval,
- const Interval* i,
+ LinearIntervalProcessor(const Sk4fGradientInterval* firstInterval,
+ const Sk4fGradientInterval* lastInterval,
+ const Sk4fGradientInterval* i,
SkScalar fx,
SkScalar dx,
bool is_vertical)
@@ -349,10 +350,10 @@ public:
private:
void compute_interval_props(SkScalar t) {
- fZeroRamp = fIsVertical || fInterval->isZeroRamp();
+ fZeroRamp = fIsVertical || fInterval->fZeroRamp;
fCc = DstTraits<dstType, premul>::load(fInterval->fC0);
- if (fInterval->isZeroRamp()) {
+ if (fInterval->fZeroRamp) {
fDcDx = 0;
} else {
const Sk4f dC = DstTraits<dstType, premul>::load(fInterval->fDc);
@@ -384,7 +385,7 @@ private:
}
}
- const Interval* next_interval(const Interval* i) const {
+ const Sk4fGradientInterval* next_interval(const Sk4fGradientInterval* i) const {
SkASSERT(i >= fFirstInterval);
SkASSERT(i <= fLastInterval);
i++;
@@ -419,11 +420,11 @@ private:
SkScalar fAdvX; // remaining interval advance in dst
bool fZeroRamp; // current interval color grad is 0
- const Interval* fFirstInterval;
- const Interval* fLastInterval;
- const Interval* fInterval; // current interval
- const SkScalar fDx; // 'dx' for consistency with other impls; actually dt/dx
- const bool fIsVertical;
+ const Sk4fGradientInterval* fFirstInterval;
+ const Sk4fGradientInterval* fLastInterval;
+ const Sk4fGradientInterval* fInterval; // current interval
+ const SkScalar fDx; // 'dx' for consistency with other impls; actually dt/dx
+ const bool fIsVertical;
};
void SkLinearGradient::
diff --git a/src/effects/gradients/Sk4fLinearGradient.h b/src/effects/gradients/Sk4fLinearGradient.h
index 762b644465..eebd30fbf5 100644
--- a/src/effects/gradients/Sk4fLinearGradient.h
+++ b/src/effects/gradients/Sk4fLinearGradient.h
@@ -38,14 +38,14 @@ private:
void shadeSpanInternal(int x, int y, typename DstTraits<dstType, premul>::Type[],
int count) const;
- const Interval* findInterval(SkScalar fx) const;
+ const Sk4fGradientInterval* findInterval(SkScalar fx) const;
bool isFast() const { return fDstToPosClass == kLinear_MatrixClass; }
static void D32_BlitBW(BlitState*, int x, int y, const SkPixmap& dst, int count);
static void D64_BlitBW(BlitState*, int x, int y, const SkPixmap& dst, int count);
- mutable const Interval* fCachedInterval;
+ mutable const Sk4fGradientInterval* fCachedInterval;
};
#endif // Sk4fLinearGradient_DEFINED