aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/shaders/gradients
diff options
context:
space:
mode:
authorGravatar Florin Malita <fmalita@chromium.org>2017-07-12 14:35:46 -0400
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2017-07-13 02:31:32 +0000
commit4d41b8f2fdae21a6ed16fca6242d53e7c08349d0 (patch)
treebce11f83330bca901f5ca7f699040c7b63293f21 /src/shaders/gradients
parent1cc3b156c40def3a0f1b02821f3edc0047961bf7 (diff)
Remove dead gradient perspective code
The cool bit here is that Sk4fLinearGradient is now always fast, and never calls the slow base-class impl. This means we can rip out Sk4fGradientBase::{mapTs, shadeSpan4f, etc}. Change-Id: Id3788bc810873b2a209f66efa4187c84b3397e2f Reviewed-on: https://skia-review.googlesource.com/22366 Reviewed-by: Herb Derby <herb@google.com> Reviewed-by: Mike Reed <reed@google.com> Commit-Queue: Florin Malita <fmalita@chromium.org>
Diffstat (limited to 'src/shaders/gradients')
-rw-r--r--src/shaders/gradients/Sk4fGradientBase.cpp125
-rw-r--r--src/shaders/gradients/Sk4fGradientBase.h15
-rw-r--r--src/shaders/gradients/Sk4fLinearGradient.cpp60
-rw-r--r--src/shaders/gradients/Sk4fLinearGradient.h6
-rw-r--r--src/shaders/gradients/SkGradientShader.cpp5
-rw-r--r--src/shaders/gradients/SkLinearGradient.cpp54
-rw-r--r--src/shaders/gradients/SkRadialGradient.cpp45
-rw-r--r--src/shaders/gradients/SkSweepGradient.cpp30
8 files changed, 38 insertions, 302 deletions
diff --git a/src/shaders/gradients/Sk4fGradientBase.cpp b/src/shaders/gradients/Sk4fGradientBase.cpp
index f5d5e7155e..0d9e6d0836 100644
--- a/src/shaders/gradients/Sk4fGradientBase.cpp
+++ b/src/shaders/gradients/Sk4fGradientBase.cpp
@@ -293,8 +293,8 @@ GradientShaderBase4fContext::GradientShaderBase4fContext(const SkGradientShaderB
const SkMatrix& inverse = this->getTotalInverse();
fDstToPos.setConcat(shader.fPtsToUnit, inverse);
+ SkASSERT(!fDstToPos.hasPerspective());
fDstToPosProc = fDstToPos.getMapXYProc();
- fDstToPosClass = static_cast<uint8_t>(INHERITED::ComputeMatrixClass(fDstToPos));
if (shader.fColorsAreOpaque && this->getPaintAlpha() == SK_AlphaOPAQUE) {
fFlags |= kOpaqueAlpha_Flag;
@@ -315,126 +315,3 @@ GradientShaderBase4fContext::shadeSpan(int x, int y, SkPMColor dst[], int count)
// This impl only shades to 4f.
SkASSERT(false);
}
-
-void SkGradientShaderBase::
-GradientShaderBase4fContext::shadeSpan4f(int x, int y, SkPM4f dst[], int count) {
- if (fColorsArePremul) {
- this->shadePremulSpan<ApplyPremul::False>(x, y, dst, count);
- } else {
- this->shadePremulSpan<ApplyPremul::True>(x, y, dst, count);
- }
-}
-
-template<ApplyPremul premul>
-void SkGradientShaderBase::
-GradientShaderBase4fContext::shadePremulSpan(int x, int y, SkPM4f dst[], int count) const {
- const SkGradientShaderBase& shader =
- static_cast<const SkGradientShaderBase&>(fShader);
-
- switch (shader.fTileMode) {
- case kClamp_TileMode:
- this->shadeSpanInternal<premul, kClamp_TileMode>(x, y, dst, count);
- break;
- case kRepeat_TileMode:
- this->shadeSpanInternal<premul, kRepeat_TileMode>(x, y, dst, count);
- break;
- case kMirror_TileMode:
- this->shadeSpanInternal<premul, kMirror_TileMode>(x, y, dst, count);
- break;
- }
-}
-
-template<ApplyPremul premul, SkShader::TileMode tileMode>
-void SkGradientShaderBase::
-GradientShaderBase4fContext::shadeSpanInternal(int x, int y, SkPM4f dst[], int count) const {
- static const int kBufSize = 128;
- SkScalar ts[kBufSize];
- TSampler<premul, tileMode> sampler(*this);
-
- SkASSERT(count > 0);
- do {
- const int n = SkTMin(kBufSize, count);
- this->mapTs(x, y, ts, n);
- for (int i = 0; i < n; ++i) {
- const Sk4f c = sampler.sample(ts[i]);
- DstTraits<premul>::store(c, dst++);
- }
- x += n;
- count -= n;
- } while (count > 0);
-}
-
-template<ApplyPremul premul, SkShader::TileMode tileMode>
-class SkGradientShaderBase::GradientShaderBase4fContext::TSampler {
-public:
- TSampler(const GradientShaderBase4fContext& ctx)
- : fCtx(ctx)
- , fInterval(nullptr) {
- switch (tileMode) {
- case kClamp_TileMode:
- fLargestIntervalValue = SK_ScalarInfinity;
- break;
- case kRepeat_TileMode:
- fLargestIntervalValue = nextafterf(1, 0);
- break;
- case kMirror_TileMode:
- fLargestIntervalValue = nextafterf(2.0f, 0);
- break;
- }
- }
-
- Sk4f sample(SkScalar t) {
- const auto tiled_t = tileProc(t);
-
- if (!fInterval) {
- // Very first sample => locate the initial interval.
- // TODO: maybe do this in ctor to remove a branch?
- fInterval = fCtx.fIntervals.find(tiled_t);
- this->loadIntervalData(fInterval);
- } else if (!fInterval->contains(tiled_t)) {
- fInterval = fCtx.fIntervals.findNext(tiled_t, fInterval, t >= fPrevT);
- this->loadIntervalData(fInterval);
- }
-
- fPrevT = t;
- return lerp(tiled_t);
- }
-
-private:
- SkScalar tileProc(SkScalar t) const {
- switch (tileMode) {
- case kClamp_TileMode:
- // synthetic clamp-mode edge intervals allow for a free-floating t:
- // [-inf..0)[0..1)[1..+inf)
- return t;
- case kRepeat_TileMode:
- // t % 1 (intervals range: [0..1))
- // Due to the extra arithmetic, we must clamp to ensure the value remains less than 1.
- return SkTMin(t - SkScalarFloorToScalar(t), fLargestIntervalValue);
- case kMirror_TileMode:
- // t % 2 (synthetic mirror intervals expand the range to [0..2)
- // Due to the extra arithmetic, we must clamp to ensure the value remains less than 2.
- return SkTMin(t - SkScalarFloorToScalar(t / 2) * 2, fLargestIntervalValue);
- }
-
- SK_ABORT("Unhandled tile mode.");
- return 0;
- }
-
- Sk4f lerp(SkScalar t) {
- SkASSERT(fInterval->contains(t));
- return fCb + fCg * t;
- }
-
- void loadIntervalData(const Sk4fGradientInterval* i) {
- fCb = DstTraits<premul>::load(i->fCb);
- fCg = DstTraits<premul>::load(i->fCg);
- }
-
- const GradientShaderBase4fContext& fCtx;
- const Sk4fGradientInterval* fInterval;
- SkScalar fPrevT;
- SkScalar fLargestIntervalValue;
- Sk4f fCb;
- Sk4f fCg;
-};
diff --git a/src/shaders/gradients/Sk4fGradientBase.h b/src/shaders/gradients/Sk4fGradientBase.h
index acba642fd7..629b0650f6 100644
--- a/src/shaders/gradients/Sk4fGradientBase.h
+++ b/src/shaders/gradients/Sk4fGradientBase.h
@@ -60,18 +60,14 @@ public:
uint32_t getFlags() const override { return fFlags; }
- void shadeSpan(int x, int y, SkPMColor dst[], int count) override;
- void shadeSpan4f(int x, int y, SkPM4f dst[], int count) override;
+ void shadeSpan(int x, int y, SkPMColor dst[], int count) final;
bool isValid() const;
protected:
- virtual void mapTs(int x, int y, SkScalar ts[], int count) const = 0;
-
Sk4fGradientIntervalBuffer fIntervals;
SkMatrix fDstToPos;
SkMatrix::MapXYProc fDstToPosProc;
- uint8_t fDstToPosClass;
uint8_t fFlags;
bool fColorsArePremul;
@@ -80,15 +76,6 @@ private:
void addMirrorIntervals(const SkGradientShaderBase&,
const Sk4f& componentScale, bool reverse);
-
- template<ApplyPremul, SkShader::TileMode tileMode>
- class TSampler;
-
- template <ApplyPremul premul>
- void shadePremulSpan(int x, int y, SkPM4f[], int count) const;
-
- template <ApplyPremul premul, SkShader::TileMode tileMode>
- void shadeSpanInternal(int x, int y, SkPM4f[], int count) const;
};
#endif // Sk4fGradientBase_DEFINED
diff --git a/src/shaders/gradients/Sk4fLinearGradient.cpp b/src/shaders/gradients/Sk4fLinearGradient.cpp
index aab1779c70..700b7fb13e 100644
--- a/src/shaders/gradients/Sk4fLinearGradient.cpp
+++ b/src/shaders/gradients/Sk4fLinearGradient.cpp
@@ -91,7 +91,7 @@ LinearGradient4fContext::LinearGradient4fContext(const SkLinearGradient& shader,
: INHERITED(shader, rec) {
// Our fast path expects interval points to be monotonically increasing in x.
- const bool reverseIntervals = this->isFast() && std::signbit(fDstToPos.getScaleX());
+ const bool reverseIntervals = std::signbit(fDstToPos.getScaleX());
fIntervals.init(shader, rec.fDstColorSpace, shader.fTileMode,
fColorsArePremul, rec.fPaint->getAlpha() * (1.0f / 255), reverseIntervals);
@@ -142,18 +142,7 @@ SkLinearGradient::LinearGradient4fContext::findInterval(SkScalar fx) const {
}
void SkLinearGradient::
-LinearGradient4fContext::shadeSpan(int x, int y, SkPMColor dst[], int count) {
- // This impl only shades to 4f.
- SkASSERT(false);
-}
-
-void SkLinearGradient::
LinearGradient4fContext::shadeSpan4f(int x, int y, SkPM4f dst[], int count) {
- if (!this->isFast()) {
- this->INHERITED::shadeSpan4f(x, y, dst, count);
- return;
- }
-
SkASSERT(count > 0);
if (fColorsArePremul) {
this->shadePremulSpan<ApplyPremul::False>(x, y, dst, count);
@@ -353,50 +342,3 @@ private:
const SkScalar fDx; // 'dx' for consistency with other impls; actually dt/dx
const bool fIsVertical;
};
-
-void SkLinearGradient::
-LinearGradient4fContext::mapTs(int x, int y, SkScalar ts[], int count) const {
- SkASSERT(count > 0);
- SkASSERT(fDstToPosClass != kLinear_MatrixClass);
-
- SkScalar sx = x + SK_ScalarHalf;
- const SkScalar sy = y + SK_ScalarHalf;
- SkPoint pt;
-
- if (fDstToPosClass != kPerspective_MatrixClass) {
- // kLinear_MatrixClass, kFixedStepInX_MatrixClass => fixed dt per scanline
- const SkScalar dtdx = fDstToPos.fixedStepInX(sy).x();
- fDstToPosProc(fDstToPos, sx, sy, &pt);
-
- const Sk4f dtdx4 = Sk4f(4 * dtdx);
- Sk4f t4 = Sk4f(pt.x() + 0 * dtdx,
- pt.x() + 1 * dtdx,
- pt.x() + 2 * dtdx,
- pt.x() + 3 * dtdx);
-
- while (count >= 4) {
- t4.store(ts);
- t4 = t4 + dtdx4;
- ts += 4;
- count -= 4;
- }
-
- if (count & 2) {
- *ts++ = t4[0];
- *ts++ = t4[1];
- t4 = SkNx_shuffle<2, 0, 1, 3>(t4);
- }
-
- if (count & 1) {
- *ts++ = t4[0];
- }
- } else {
- for (int i = 0; i < count; ++i) {
- fDstToPosProc(fDstToPos, sx, sy, &pt);
- // Perspective may yield NaN values.
- // Short of a better idea, drop to 0.
- ts[i] = SkScalarIsNaN(pt.x()) ? 0 : pt.x();
- sx += SK_Scalar1;
- }
- }
-}
diff --git a/src/shaders/gradients/Sk4fLinearGradient.h b/src/shaders/gradients/Sk4fLinearGradient.h
index 96af4dfced..11606e1c80 100644
--- a/src/shaders/gradients/Sk4fLinearGradient.h
+++ b/src/shaders/gradients/Sk4fLinearGradient.h
@@ -16,12 +16,8 @@ LinearGradient4fContext final : public GradientShaderBase4fContext {
public:
LinearGradient4fContext(const SkLinearGradient&, const ContextRec&);
- void shadeSpan(int x, int y, SkPMColor dst[], int count) override;
void shadeSpan4f(int x, int y, SkPM4f dst[], int count) override;
-protected:
- void mapTs(int x, int y, SkScalar ts[], int count) const override;
-
private:
using INHERITED = GradientShaderBase4fContext;
@@ -36,8 +32,6 @@ private:
const Sk4fGradientInterval* findInterval(SkScalar fx) const;
- bool isFast() const { return fDstToPosClass == kLinear_MatrixClass; }
-
mutable const Sk4fGradientInterval* fCachedInterval;
};
diff --git a/src/shaders/gradients/SkGradientShader.cpp b/src/shaders/gradients/SkGradientShader.cpp
index 0619ef0546..63770185b4 100644
--- a/src/shaders/gradients/SkGradientShader.cpp
+++ b/src/shaders/gradients/SkGradientShader.cpp
@@ -534,12 +534,9 @@ SkGradientShaderBase::GradientShaderBaseContext::GradientShaderBaseContext(
const SkMatrix& inverse = this->getTotalInverse();
fDstToIndex.setConcat(shader.fPtsToUnit, inverse);
+ SkASSERT(!fDstToIndex.hasPerspective());
fDstToIndexProc = fDstToIndex.getMapXYProc();
- fDstToIndexClass = (uint8_t)SkShaderBase::Context::ComputeMatrixClass(fDstToIndex);
-
- // TODO: remove all perspective-related gradient code
- SkASSERT(fDstToIndexClass == kLinear_MatrixClass);
// now convert our colors in to PMColors
unsigned paintAlpha = this->getPaintAlpha();
diff --git a/src/shaders/gradients/SkLinearGradient.cpp b/src/shaders/gradients/SkLinearGradient.cpp
index 08ce2db813..fc49d3430d 100644
--- a/src/shaders/gradients/SkLinearGradient.cpp
+++ b/src/shaders/gradients/SkLinearGradient.cpp
@@ -285,9 +285,7 @@ void SkLinearGradient::LinearGradientContext::shadeSpan(int x, int y, SkPMColor*
SkASSERT(count > 0);
const SkLinearGradient& linearGradient = static_cast<const SkLinearGradient&>(fShader);
- if (SkShader::kClamp_TileMode == linearGradient.fTileMode &&
- kLinear_MatrixClass == fDstToIndexClass)
- {
+ if (SkShader::kClamp_TileMode == linearGradient.fTileMode) {
this->shade4_clamp(x, y, dstC, count);
return;
}
@@ -298,43 +296,22 @@ void SkLinearGradient::LinearGradientContext::shadeSpan(int x, int y, SkPMColor*
const SkPMColor* SK_RESTRICT cache = fCache->getCache32();
int toggle = init_dither_toggle(x, y);
- if (fDstToIndexClass != kPerspective_MatrixClass) {
- dstProc(fDstToIndex, SkIntToScalar(x) + SK_ScalarHalf,
- SkIntToScalar(y) + SK_ScalarHalf, &srcPt);
- SkGradFixed dx, fx = SkScalarPinToGradFixed(srcPt.fX);
-
- if (fDstToIndexClass == kFixedStepInX_MatrixClass) {
- const auto step = fDstToIndex.fixedStepInX(SkIntToScalar(y));
- // todo: do we need a real/high-precision value for dx here?
- dx = SkScalarPinToGradFixed(step.fX);
- } else {
- SkASSERT(fDstToIndexClass == kLinear_MatrixClass);
- dx = SkScalarPinToGradFixed(fDstToIndex.getScaleX());
- }
-
- LinearShadeProc shadeProc = shadeSpan_linear_repeat;
- if (0 == dx) {
- shadeProc = shadeSpan_linear_vertical_lerp;
- } else if (SkShader::kClamp_TileMode == linearGradient.fTileMode) {
- shadeProc = shadeSpan_linear_clamp;
- } else if (SkShader::kMirror_TileMode == linearGradient.fTileMode) {
- shadeProc = shadeSpan_linear_mirror;
- } else {
- SkASSERT(SkShader::kRepeat_TileMode == linearGradient.fTileMode);
- }
- (*shadeProc)(proc, dx, fx, dstC, cache, toggle, count);
+ dstProc(fDstToIndex, SkIntToScalar(x) + SK_ScalarHalf,
+ SkIntToScalar(y) + SK_ScalarHalf, &srcPt);
+ SkGradFixed fx = SkScalarPinToGradFixed(srcPt.fX),
+ dx = SkScalarPinToGradFixed(fDstToIndex.getScaleX());
+
+ LinearShadeProc shadeProc = shadeSpan_linear_repeat;
+ if (0 == dx) {
+ shadeProc = shadeSpan_linear_vertical_lerp;
+ } else if (SkShader::kClamp_TileMode == linearGradient.fTileMode) {
+ shadeProc = shadeSpan_linear_clamp;
+ } else if (SkShader::kMirror_TileMode == linearGradient.fTileMode) {
+ shadeProc = shadeSpan_linear_mirror;
} else {
- SkScalar dstX = SkIntToScalar(x);
- SkScalar dstY = SkIntToScalar(y);
- do {
- dstProc(fDstToIndex, dstX, dstY, &srcPt);
- unsigned fi = proc(SkScalarToFixed(srcPt.fX));
- SkASSERT(fi <= 0xFFFF);
- *dstC++ = cache[toggle + (fi >> kCache32Shift)];
- toggle = next_dither_toggle(toggle);
- dstX += SK_Scalar1;
- } while (--count != 0);
+ SkASSERT(SkShader::kRepeat_TileMode == linearGradient.fTileMode);
}
+ (*shadeProc)(proc, dx, fx, dstC, cache, toggle, count);
}
SkShader::GradientType SkLinearGradient::asAGradient(GradientInfo* info) const {
@@ -756,7 +733,6 @@ void SkLinearGradient::LinearGradientContext::shade4_dx_clamp(SkPMColor dstC[],
void SkLinearGradient::LinearGradientContext::shade4_clamp(int x, int y, SkPMColor dstC[],
int count) {
SkASSERT(count > 0);
- SkASSERT(kLinear_MatrixClass == fDstToIndexClass);
SkPoint srcPt;
fDstToIndexProc(fDstToIndex, x + SK_ScalarHalf, y + SK_ScalarHalf, &srcPt);
diff --git a/src/shaders/gradients/SkRadialGradient.cpp b/src/shaders/gradients/SkRadialGradient.cpp
index 06135e8e01..0a6a940b18 100644
--- a/src/shaders/gradients/SkRadialGradient.cpp
+++ b/src/shaders/gradients/SkRadialGradient.cpp
@@ -194,44 +194,23 @@ void SkRadialGradient::RadialGradientContext::shadeSpan(int x, int y,
SkPoint srcPt;
SkMatrix::MapXYProc dstProc = fDstToIndexProc;
- TileProc proc = radialGradient.fTileProc;
const SkPMColor* SK_RESTRICT cache = fCache->getCache32();
int toggle = init_dither_toggle(x, y);
- if (fDstToIndexClass != kPerspective_MatrixClass) {
- dstProc(fDstToIndex, SkIntToScalar(x) + SK_ScalarHalf,
- SkIntToScalar(y) + SK_ScalarHalf, &srcPt);
- SkScalar sdx = fDstToIndex.getScaleX();
- SkScalar sdy = fDstToIndex.getSkewY();
-
- if (fDstToIndexClass == kFixedStepInX_MatrixClass) {
- const auto step = fDstToIndex.fixedStepInX(SkIntToScalar(y));
- sdx = step.fX;
- sdy = step.fY;
- } else {
- SkASSERT(fDstToIndexClass == kLinear_MatrixClass);
- }
+ dstProc(fDstToIndex, SkIntToScalar(x) + SK_ScalarHalf,
+ SkIntToScalar(y) + SK_ScalarHalf, &srcPt);
+ SkScalar sdx = fDstToIndex.getScaleX();
+ SkScalar sdy = fDstToIndex.getSkewY();
- RadialShadeProc shadeProc = shadeSpan_radial_repeat;
- if (SkShader::kClamp_TileMode == radialGradient.fTileMode) {
- shadeProc = shadeSpan_radial_clamp2;
- } else if (SkShader::kMirror_TileMode == radialGradient.fTileMode) {
- shadeProc = shadeSpan_radial_mirror;
- } else {
- SkASSERT(SkShader::kRepeat_TileMode == radialGradient.fTileMode);
- }
- (*shadeProc)(srcPt.fX, sdx, srcPt.fY, sdy, dstC, cache, count, toggle);
- } else { // perspective case
- SkScalar dstX = SkIntToScalar(x);
- SkScalar dstY = SkIntToScalar(y);
- do {
- dstProc(fDstToIndex, dstX, dstY, &srcPt);
- unsigned fi = proc(SkScalarToFixed(srcPt.length()));
- SkASSERT(fi <= 0xFFFF);
- *dstC++ = cache[fi >> SkGradientShaderBase::kCache32Shift];
- dstX += SK_Scalar1;
- } while (--count != 0);
+ RadialShadeProc shadeProc = shadeSpan_radial_repeat;
+ if (SkShader::kClamp_TileMode == radialGradient.fTileMode) {
+ shadeProc = shadeSpan_radial_clamp2;
+ } else if (SkShader::kMirror_TileMode == radialGradient.fTileMode) {
+ shadeProc = shadeSpan_radial_mirror;
+ } else {
+ SkASSERT(SkShader::kRepeat_TileMode == radialGradient.fTileMode);
}
+ (*shadeProc)(srcPt.fX, sdx, srcPt.fY, sdy, dstC, cache, count, toggle);
}
/////////////////////////////////////////////////////////////////////
diff --git a/src/shaders/gradients/SkSweepGradient.cpp b/src/shaders/gradients/SkSweepGradient.cpp
index 61ddf5c39b..e6bc42c20e 100644
--- a/src/shaders/gradients/SkSweepGradient.cpp
+++ b/src/shaders/gradients/SkSweepGradient.cpp
@@ -98,21 +98,13 @@ void SkSweepGradient::SweepGradientContext::shadeSpan(int x, int y, SkPMColor* S
int toggle = init_dither_toggle(x, y);
SkPoint srcPt;
- if (fDstToIndexClass != kPerspective_MatrixClass) {
- proc(matrix, SkIntToScalar(x) + SK_ScalarHalf,
- SkIntToScalar(y) + SK_ScalarHalf, &srcPt);
- SkScalar dx, fx = srcPt.fX;
- SkScalar dy, fy = srcPt.fY;
-
- if (fDstToIndexClass == kFixedStepInX_MatrixClass) {
- const auto step = matrix.fixedStepInX(SkIntToScalar(y) + SK_ScalarHalf);
- dx = step.fX;
- dy = step.fY;
- } else {
- SkASSERT(fDstToIndexClass == kLinear_MatrixClass);
- dx = matrix.getScaleX();
- dy = matrix.getSkewY();
- }
+ proc(matrix, SkIntToScalar(x) + SK_ScalarHalf,
+ SkIntToScalar(y) + SK_ScalarHalf, &srcPt);
+ SkScalar fx = srcPt.fX,
+ fy = srcPt.fY;
+
+ SkScalar dx = matrix.getScaleX(),
+ dy = matrix.getSkewY();
for (; count > 0; --count) {
*dstC++ = cache[toggle + SkATan2_255(fy, fx)];
@@ -120,14 +112,6 @@ void SkSweepGradient::SweepGradientContext::shadeSpan(int x, int y, SkPMColor* S
fy += dy;
toggle = next_dither_toggle(toggle);
}
- } else { // perspective case
- for (int stop = x + count; x < stop; x++) {
- proc(matrix, SkIntToScalar(x) + SK_ScalarHalf,
- SkIntToScalar(y) + SK_ScalarHalf, &srcPt);
- *dstC++ = cache[toggle + SkATan2_255(srcPt.fY, srcPt.fX)];
- toggle = next_dither_toggle(toggle);
- }
- }
}
/////////////////////////////////////////////////////////////////////