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

Side by Side Diff: third_party/WebKit/Source/platform/graphics/Gradient.cpp

Issue 2893083002: cc: Move SkShader construction to a single spot in PaintShader (Closed)
Patch Set: update Created 3 years, 6 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
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2006, 2007, 2008, 2010 Apple Inc. All rights reserved. 2 * Copyright (C) 2006, 2007, 2008, 2010 Apple Inc. All rights reserved.
3 * Copyright (C) 2007 Alp Toker <alp@atoker.com> 3 * Copyright (C) 2007 Alp Toker <alp@atoker.com>
4 * Copyright (C) 2013 Google Inc. All rights reserved. 4 * Copyright (C) 2013 Google Inc. All rights reserved.
5 * 5 *
6 * Redistribution and use in source and binary forms, with or without 6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions 7 * modification, are permitted provided that the following conditions
8 * are met: 8 * are met:
9 * 1. Redistributions of source code must retain the above copyright 9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer. 10 * notice, this list of conditions and the following disclaimer.
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
114 114
115 // Copy the last stop to 1.0 if needed. See comment above about this float 115 // Copy the last stop to 1.0 if needed. See comment above about this float
116 // comparison. 116 // comparison.
117 DCHECK(!pos.IsEmpty()); 117 DCHECK(!pos.IsEmpty());
118 if (pos.back() < 1) { 118 if (pos.back() < 1) {
119 pos.push_back(WebCoreFloatToSkScalar(1)); 119 pos.push_back(WebCoreFloatToSkScalar(1));
120 colors.push_back(colors.back()); 120 colors.push_back(colors.back());
121 } 121 }
122 } 122 }
123 123
124 sk_sp<PaintShader> Gradient::CreateShaderInternal( 124 std::unique_ptr<PaintShader> Gradient::CreateShaderInternal(
125 const SkMatrix& local_matrix) { 125 const SkMatrix& local_matrix) {
126 SortStopsIfNecessary(); 126 SortStopsIfNecessary();
127 DCHECK(stops_sorted_); 127 DCHECK(stops_sorted_);
128 128
129 ColorBuffer colors; 129 ColorBuffer colors;
130 colors.ReserveCapacity(stops_.size()); 130 colors.ReserveCapacity(stops_.size());
131 OffsetBuffer pos; 131 OffsetBuffer pos;
132 pos.ReserveCapacity(stops_.size()); 132 pos.ReserveCapacity(stops_.size());
133 133
134 FillSkiaStops(colors, pos); 134 FillSkiaStops(colors, pos);
135 DCHECK_GE(colors.size(), 2ul); 135 DCHECK_GE(colors.size(), 2ul);
136 DCHECK_EQ(pos.size(), colors.size()); 136 DCHECK_EQ(pos.size(), colors.size());
137 137
138 SkShader::TileMode tile = SkShader::kClamp_TileMode; 138 SkShader::TileMode tile = SkShader::kClamp_TileMode;
139 switch (spread_method_) { 139 switch (spread_method_) {
140 case kSpreadMethodReflect: 140 case kSpreadMethodReflect:
141 tile = SkShader::kMirror_TileMode; 141 tile = SkShader::kMirror_TileMode;
142 break; 142 break;
143 case kSpreadMethodRepeat: 143 case kSpreadMethodRepeat:
144 tile = SkShader::kRepeat_TileMode; 144 tile = SkShader::kRepeat_TileMode;
145 break; 145 break;
146 case kSpreadMethodPad: 146 case kSpreadMethodPad:
147 tile = SkShader::kClamp_TileMode; 147 tile = SkShader::kClamp_TileMode;
148 break; 148 break;
149 } 149 }
150 150
151 uint32_t flags = color_interpolation_ == ColorInterpolation::kPremultiplied 151 uint32_t flags = color_interpolation_ == ColorInterpolation::kPremultiplied
152 ? SkGradientShader::kInterpolateColorsInPremul_Flag 152 ? SkGradientShader::kInterpolateColorsInPremul_Flag
153 : 0; 153 : 0;
154 sk_sp<SkShader> shader = CreateShader(colors, pos, tile, flags, local_matrix); 154 std::unique_ptr<PaintShader> shader =
155 if (!shader) { 155 CreateShader(colors, pos, tile, flags, local_matrix, colors.back());
156 // use last color, since our "geometry" was degenerate (e.g. radius==0) 156 DCHECK(shader);
157 shader = SkShader::MakeColorShader(colors.back());
158 }
159 157
160 return WrapSkShader(std::move(shader)); 158 return shader;
161 } 159 }
162 160
163 void Gradient::ApplyToFlags(PaintFlags& flags, const SkMatrix& local_matrix) { 161 void Gradient::ApplyToFlags(PaintFlags& flags, const SkMatrix& local_matrix) {
164 if (!cached_shader_ || local_matrix != cached_shader_->getLocalMatrix()) 162 if (!cached_shader_ ||
163 local_matrix != cached_shader_->sk_shader()->getLocalMatrix()) {
165 cached_shader_ = CreateShaderInternal(local_matrix); 164 cached_shader_ = CreateShaderInternal(local_matrix);
165 }
166 166
167 flags.setShader(cached_shader_); 167 flags.setShader(WTF::MakeUnique<PaintShader>(*cached_shader_));
168 168
169 // Legacy behavior: gradients are always dithered. 169 // Legacy behavior: gradients are always dithered.
170 flags.setDither(true); 170 flags.setDither(true);
171 } 171 }
172 172
173 namespace { 173 namespace {
174 174
175 class LinearGradient final : public Gradient { 175 class LinearGradient final : public Gradient {
176 public: 176 public:
177 LinearGradient(const FloatPoint& p0, 177 LinearGradient(const FloatPoint& p0,
178 const FloatPoint& p1, 178 const FloatPoint& p1,
179 GradientSpreadMethod spread_method, 179 GradientSpreadMethod spread_method,
180 ColorInterpolation interpolation) 180 ColorInterpolation interpolation)
181 : Gradient(Type::kLinear, spread_method, interpolation), 181 : Gradient(Type::kLinear, spread_method, interpolation),
182 p0_(p0), 182 p0_(p0),
183 p1_(p1) {} 183 p1_(p1) {}
184 184
185 protected: 185 protected:
186 sk_sp<SkShader> CreateShader(const ColorBuffer& colors, 186 std::unique_ptr<PaintShader> CreateShader(
187 const OffsetBuffer& pos, 187 const ColorBuffer& colors,
188 SkShader::TileMode tile_mode, 188 const OffsetBuffer& pos,
189 uint32_t flags, 189 SkShader::TileMode tile_mode,
190 const SkMatrix& local_matrix) const override { 190 uint32_t flags,
191 const SkMatrix& local_matrix,
192 SkColor fallback_color) const override {
191 SkPoint pts[2] = {p0_.Data(), p1_.Data()}; 193 SkPoint pts[2] = {p0_.Data(), p1_.Data()};
192 return SkGradientShader::MakeLinear(pts, colors.data(), pos.data(), 194 return PaintShader::MakeLinearGradient(
193 static_cast<int>(colors.size()), 195 pts, colors.data(), pos.data(), static_cast<int>(colors.size()),
194 tile_mode, flags, &local_matrix); 196 tile_mode, flags, &local_matrix, fallback_color);
195 } 197 }
196 198
197 private: 199 private:
198 const FloatPoint p0_; 200 const FloatPoint p0_;
199 const FloatPoint p1_; 201 const FloatPoint p1_;
200 }; 202 };
201 203
202 class RadialGradient final : public Gradient { 204 class RadialGradient final : public Gradient {
203 public: 205 public:
204 RadialGradient(const FloatPoint& p0, 206 RadialGradient(const FloatPoint& p0,
205 float r0, 207 float r0,
206 const FloatPoint& p1, 208 const FloatPoint& p1,
207 float r1, 209 float r1,
208 float aspect_ratio, 210 float aspect_ratio,
209 GradientSpreadMethod spread_method, 211 GradientSpreadMethod spread_method,
210 ColorInterpolation interpolation) 212 ColorInterpolation interpolation)
211 : Gradient(Type::kRadial, spread_method, interpolation), 213 : Gradient(Type::kRadial, spread_method, interpolation),
212 p0_(p0), 214 p0_(p0),
213 p1_(p1), 215 p1_(p1),
214 r0_(r0), 216 r0_(r0),
215 r1_(r1), 217 r1_(r1),
216 aspect_ratio_(aspect_ratio) {} 218 aspect_ratio_(aspect_ratio) {}
217 219
218 protected: 220 protected:
219 sk_sp<SkShader> CreateShader(const ColorBuffer& colors, 221 std::unique_ptr<PaintShader> CreateShader(
220 const OffsetBuffer& pos, 222 const ColorBuffer& colors,
221 SkShader::TileMode tile_mode, 223 const OffsetBuffer& pos,
222 uint32_t flags, 224 SkShader::TileMode tile_mode,
223 const SkMatrix& local_matrix) const override { 225 uint32_t flags,
226 const SkMatrix& local_matrix,
227 SkColor fallback_color) const override {
224 SkTCopyOnFirstWrite<SkMatrix> adjusted_local_matrix(local_matrix); 228 SkTCopyOnFirstWrite<SkMatrix> adjusted_local_matrix(local_matrix);
225 if (aspect_ratio_ != 1) { 229 if (aspect_ratio_ != 1) {
226 // CSS3 elliptical gradients: apply the elliptical scaling at the 230 // CSS3 elliptical gradients: apply the elliptical scaling at the
227 // gradient center point. 231 // gradient center point.
228 DCHECK(p0_ == p1_); 232 DCHECK(p0_ == p1_);
229 adjusted_local_matrix.writable()->preScale(1, 1 / aspect_ratio_, p0_.X(), 233 adjusted_local_matrix.writable()->preScale(1, 1 / aspect_ratio_, p0_.X(),
230 p0_.Y()); 234 p0_.Y());
231 } 235 }
232 236
233 // Since the two-point radial gradient is slower than the plain radial, 237 // Since the two-point radial gradient is slower than the plain radial,
234 // only use it if we have to. 238 // only use it if we have to.
235 if (p0_ == p1_ && r0_ <= 0.0f) { 239 if (p0_ == p1_ && r0_ <= 0.0f) {
236 return SkGradientShader::MakeRadial( 240 return PaintShader::MakeRadialGradient(
237 p1_.Data(), r1_, colors.data(), pos.data(), 241 p1_.Data(), r1_, colors.data(), pos.data(),
238 static_cast<int>(colors.size()), tile_mode, flags, 242 static_cast<int>(colors.size()), tile_mode, flags,
239 adjusted_local_matrix); 243 adjusted_local_matrix, fallback_color);
240 } 244 }
241 245
242 // The radii we give to Skia must be positive. If we're given a 246 // The radii we give to Skia must be positive. If we're given a
243 // negative radius, ask for zero instead. 247 // negative radius, ask for zero instead.
244 const SkScalar radius0 = std::max(WebCoreFloatToSkScalar(r0_), 0.0f); 248 const SkScalar radius0 = std::max(WebCoreFloatToSkScalar(r0_), 0.0f);
245 const SkScalar radius1 = std::max(WebCoreFloatToSkScalar(r1_), 0.0f); 249 const SkScalar radius1 = std::max(WebCoreFloatToSkScalar(r1_), 0.0f);
246 return SkGradientShader::MakeTwoPointConical( 250 return PaintShader::MakeTwoPointConicalGradient(
247 p0_.Data(), radius0, p1_.Data(), radius1, colors.data(), pos.data(), 251 p0_.Data(), radius0, p1_.Data(), radius1, colors.data(), pos.data(),
248 static_cast<int>(colors.size()), tile_mode, flags, 252 static_cast<int>(colors.size()), tile_mode, flags,
249 adjusted_local_matrix); 253 adjusted_local_matrix, fallback_color);
250 } 254 }
251 255
252 private: 256 private:
253 const FloatPoint p0_; 257 const FloatPoint p0_;
254 const FloatPoint p1_; 258 const FloatPoint p1_;
255 const float r0_; 259 const float r0_;
256 const float r1_; 260 const float r1_;
257 const float aspect_ratio_; // For elliptical gradient, width / height. 261 const float aspect_ratio_; // For elliptical gradient, width / height.
258 }; 262 };
259 263
260 class ConicGradient final : public Gradient { 264 class ConicGradient final : public Gradient {
261 public: 265 public:
262 ConicGradient(const FloatPoint& position, 266 ConicGradient(const FloatPoint& position,
263 float angle, 267 float angle,
264 ColorInterpolation interpolation) 268 ColorInterpolation interpolation)
265 : Gradient(Type::kConic, kSpreadMethodPad, interpolation), 269 : Gradient(Type::kConic, kSpreadMethodPad, interpolation),
266 position_(position), 270 position_(position),
267 angle_(angle) {} 271 angle_(angle) {}
268 272
269 protected: 273 protected:
270 sk_sp<SkShader> CreateShader(const ColorBuffer& colors, 274 std::unique_ptr<PaintShader> CreateShader(
271 const OffsetBuffer& pos, 275 const ColorBuffer& colors,
272 SkShader::TileMode tile_mode, 276 const OffsetBuffer& pos,
273 uint32_t flags, 277 SkShader::TileMode tile_mode,
274 const SkMatrix& local_matrix) const override { 278 uint32_t flags,
279 const SkMatrix& local_matrix,
280 SkColor fallback_color) const override {
275 DCHECK_NE(tile_mode, SkShader::kMirror_TileMode); 281 DCHECK_NE(tile_mode, SkShader::kMirror_TileMode);
276 282
277 // Skia's sweep gradient angles are relative to the x-axis, not the y-axis. 283 // Skia's sweep gradient angles are relative to the x-axis, not the y-axis.
278 const float skia_angle = angle_ - 90; 284 const float skia_angle = angle_ - 90;
279 SkTCopyOnFirstWrite<SkMatrix> adjusted_local_matrix(local_matrix); 285 SkTCopyOnFirstWrite<SkMatrix> adjusted_local_matrix(local_matrix);
280 if (skia_angle) { 286 if (skia_angle) {
281 adjusted_local_matrix.writable()->preRotate(skia_angle, position_.X(), 287 adjusted_local_matrix.writable()->preRotate(skia_angle, position_.X(),
282 position_.Y()); 288 position_.Y());
283 } 289 }
284 290
285 return SkGradientShader::MakeSweep( 291 return PaintShader::MakeSweepGradient(
286 position_.X(), position_.Y(), colors.data(), pos.data(), 292 position_.X(), position_.Y(), colors.data(), pos.data(),
287 static_cast<int>(colors.size()), flags, adjusted_local_matrix); 293 static_cast<int>(colors.size()), flags, adjusted_local_matrix,
294 fallback_color);
288 } 295 }
289 296
290 private: 297 private:
291 const FloatPoint position_; 298 const FloatPoint position_;
292 const float angle_; 299 const float angle_;
293 }; 300 };
294 301
295 } // anonymous ns 302 } // anonymous ns
296 303
297 PassRefPtr<Gradient> Gradient::CreateLinear(const FloatPoint& p0, 304 PassRefPtr<Gradient> Gradient::CreateLinear(const FloatPoint& p0,
(...skipping 14 matching lines...) Expand all
312 spread_method, interpolation)); 319 spread_method, interpolation));
313 } 320 }
314 321
315 PassRefPtr<Gradient> Gradient::CreateConic(const FloatPoint& position, 322 PassRefPtr<Gradient> Gradient::CreateConic(const FloatPoint& position,
316 float angle, 323 float angle,
317 ColorInterpolation interpolation) { 324 ColorInterpolation interpolation) {
318 return AdoptRef(new ConicGradient(position, angle, interpolation)); 325 return AdoptRef(new ConicGradient(position, angle, interpolation));
319 } 326 }
320 327
321 } // namespace blink 328 } // namespace blink
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/platform/graphics/Gradient.h ('k') | third_party/WebKit/Source/platform/graphics/Image.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698