Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(57)

Side by Side Diff: src/effects/gradients/Sk4fLinearGradient.cpp

Issue 2349153004: Harden LinearGradient4fContext (Closed)
Patch Set: Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | src/effects/gradients/SkGradientShader.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright 2016 Google Inc. 2 * Copyright 2016 Google Inc.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license that can be 4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file. 5 * found in the LICENSE file.
6 */ 6 */
7 7
8 #include "Sk4fLinearGradient.h" 8 #include "Sk4fLinearGradient.h"
9 #include "Sk4x4f.h" 9 #include "Sk4x4f.h"
10 #include "SkXfermode.h" 10 #include "SkXfermode.h"
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
93 const SkScalar f = SkScalarFraction(fx); 93 const SkScalar f = SkScalarFraction(fx);
94 return f < 0 ? f + 1 : f; 94 return f < 0 ? f + 1 : f;
95 } 95 }
96 96
97 template<> 97 template<>
98 SkScalar pinFx<SkShader::kMirror_TileMode>(SkScalar fx) { 98 SkScalar pinFx<SkShader::kMirror_TileMode>(SkScalar fx) {
99 const SkScalar f = SkScalarMod(fx, 2.0f); 99 const SkScalar f = SkScalarMod(fx, 2.0f);
100 return f < 0 ? f + 2 : f; 100 return f < 0 ? f + 2 : f;
101 } 101 }
102 102
103 // true when x is in [k1,k2) 103 // true when x is in [k1,k2), or [k2, k1) when the interval is reversed.
104 // TODO(fmalita): hoist the reversed interval check out of this helper.
104 bool in_range(SkScalar x, SkScalar k1, SkScalar k2) { 105 bool in_range(SkScalar x, SkScalar k1, SkScalar k2) {
105 SkASSERT(k1 != k2); 106 SkASSERT(k1 != k2);
106 return (k1 < k2) 107 return (k1 < k2)
107 ? (x >= k1 && x < k2) 108 ? (x >= k1 && x < k2)
108 : (x >= k2 && x < k1); 109 : (x > k2 && x <= k1);
109 } 110 }
110 111
111 } // anonymous namespace 112 } // anonymous namespace
112 113
113 SkLinearGradient:: 114 SkLinearGradient::
114 LinearGradient4fContext::LinearGradient4fContext(const SkLinearGradient& shader, 115 LinearGradient4fContext::LinearGradient4fContext(const SkLinearGradient& shader,
115 const ContextRec& rec) 116 const ContextRec& rec)
116 : INHERITED(shader, rec) { 117 : INHERITED(shader, rec) {
117 118
118 // Our fast path expects interval points to be monotonically increasing in x . 119 // Our fast path expects interval points to be monotonically increasing in x .
119 const bool reverseIntervals = this->isFast() && fDstToPos.getScaleX() < 0; 120 const bool reverseIntervals = this->isFast() && signbit(fDstToPos.getScaleX( ));
120 this->buildIntervals(shader, rec, reverseIntervals); 121 this->buildIntervals(shader, rec, reverseIntervals);
121 122
122 SkASSERT(fIntervals.count() > 0); 123 SkASSERT(fIntervals.count() > 0);
123 fCachedInterval = fIntervals.begin(); 124 fCachedInterval = fIntervals.begin();
124 } 125 }
125 126
126 const SkGradientShaderBase::GradientShaderBase4fContext::Interval* 127 const SkGradientShaderBase::GradientShaderBase4fContext::Interval*
127 SkLinearGradient::LinearGradient4fContext::findInterval(SkScalar fx) const { 128 SkLinearGradient::LinearGradient4fContext::findInterval(SkScalar fx) const {
128 SkASSERT(in_range(fx, fIntervals.front().fP0, fIntervals.back().fP1)); 129 SkASSERT(in_range(fx, fIntervals.front().fP0, fIntervals.back().fP1));
129 130
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after
283 SkScalar fx, 284 SkScalar fx,
284 SkScalar dx, 285 SkScalar dx,
285 bool is_vertical) 286 bool is_vertical)
286 : fAdvX((i->fP1 - fx) / dx) 287 : fAdvX((i->fP1 - fx) / dx)
287 , fFirstInterval(firstInterval) 288 , fFirstInterval(firstInterval)
288 , fLastInterval(lastInterval) 289 , fLastInterval(lastInterval)
289 , fInterval(i) 290 , fInterval(i)
290 , fDx(dx) 291 , fDx(dx)
291 , fIsVertical(is_vertical) 292 , fIsVertical(is_vertical)
292 { 293 {
294 SkASSERT(fAdvX >= 0);
293 SkASSERT(firstInterval <= lastInterval); 295 SkASSERT(firstInterval <= lastInterval);
294 SkASSERT(in_range(fx, i->fP0, i->fP1)); 296 SkASSERT(in_range(fx, i->fP0, i->fP1));
295 this->compute_interval_props(fx - i->fP0); 297 this->compute_interval_props(fx - i->fP0);
296 } 298 }
297 299
298 SkScalar currentAdvance() const { 300 SkScalar currentAdvance() const {
299 SkASSERT(fAdvX >= 0); 301 SkASSERT(fAdvX >= 0);
300 SkASSERT(fAdvX <= (fInterval->fP1 - fInterval->fP0) / fDx); 302 SkASSERT(fAdvX <= (fInterval->fP1 - fInterval->fP0) / fDx);
301 return fAdvX; 303 return fAdvX;
302 } 304 }
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after
472 static_cast<const LinearGradient4fContext*>(state->fCtx); 474 static_cast<const LinearGradient4fContext*>(state->fCtx);
473 475
474 if (ctx->fColorsArePremul) { 476 if (ctx->fColorsArePremul) {
475 ctx->shadePremulSpan<DstType::F16, ApplyPremul::False>( 477 ctx->shadePremulSpan<DstType::F16, ApplyPremul::False>(
476 x, y, dst.writable_addr64(x, y), count); 478 x, y, dst.writable_addr64(x, y), count);
477 } else { 479 } else {
478 ctx->shadePremulSpan<DstType::F16, ApplyPremul::True>( 480 ctx->shadePremulSpan<DstType::F16, ApplyPremul::True>(
479 x, y, dst.writable_addr64(x, y), count); 481 x, y, dst.writable_addr64(x, y), count);
480 } 482 }
481 } 483 }
OLDNEW
« no previous file with comments | « no previous file | src/effects/gradients/SkGradientShader.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698