OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2012 Google Inc. | 2 * Copyright 2012 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 "GrGLPath.h" | 8 #include "GrGLPath.h" |
9 #include "GrGLPathRendering.h" | 9 #include "GrGLPathRendering.h" |
10 #include "GrGLGpu.h" | 10 #include "GrGLGpu.h" |
| 11 #include "GrStyle.h" |
11 | 12 |
12 namespace { | 13 namespace { |
13 inline GrGLubyte verb_to_gl_path_cmd(SkPath::Verb verb) { | 14 inline GrGLubyte verb_to_gl_path_cmd(SkPath::Verb verb) { |
14 static const GrGLubyte gTable[] = { | 15 static const GrGLubyte gTable[] = { |
15 GR_GL_MOVE_TO, | 16 GR_GL_MOVE_TO, |
16 GR_GL_LINE_TO, | 17 GR_GL_LINE_TO, |
17 GR_GL_QUADRATIC_CURVE_TO, | 18 GR_GL_QUADRATIC_CURVE_TO, |
18 GR_GL_CONIC_CURVE_TO, | 19 GR_GL_CONIC_CURVE_TO, |
19 GR_GL_CUBIC_CURVE_TO, | 20 GR_GL_CUBIC_CURVE_TO, |
20 GR_GL_CLOSE_PATH, | 21 GR_GL_CLOSE_PATH, |
(...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
244 SkDEBUGCODE(verify_floats(&pathCoords[0], pathCoords.count())); | 245 SkDEBUGCODE(verify_floats(&pathCoords[0], pathCoords.count())); |
245 GR_GL_CALL(gpu->glInterface(), PathCommands(pathID, pathCommands.count()
, &pathCommands[0], | 246 GR_GL_CALL(gpu->glInterface(), PathCommands(pathID, pathCommands.count()
, &pathCommands[0], |
246 pathCoords.count(), GR_GL_FL
OAT, | 247 pathCoords.count(), GR_GL_FL
OAT, |
247 &pathCoords[0])); | 248 &pathCoords[0])); |
248 return; | 249 return; |
249 } | 250 } |
250 #endif | 251 #endif |
251 SkAssertResult(init_path_object_for_general_path<false>(gpu, pathID, skPath)
); | 252 SkAssertResult(init_path_object_for_general_path<false>(gpu, pathID, skPath)
); |
252 } | 253 } |
253 | 254 |
254 void GrGLPath::InitPathObjectStroke(GrGLGpu* gpu, GrGLuint pathID, const GrStrok
eInfo& stroke) { | 255 void GrGLPath::InitPathObjectStroke(GrGLGpu* gpu, GrGLuint pathID, const SkStrok
eRec& stroke) { |
255 SkASSERT(stroke.needToApply()); | |
256 SkASSERT(!stroke.isDashed()); | |
257 SkASSERT(!stroke.isHairlineStyle()); | 256 SkASSERT(!stroke.isHairlineStyle()); |
258 GR_GL_CALL(gpu->glInterface(), | 257 GR_GL_CALL(gpu->glInterface(), |
259 PathParameterf(pathID, GR_GL_PATH_STROKE_WIDTH, SkScalarToFloat(s
troke.getWidth()))); | 258 PathParameterf(pathID, GR_GL_PATH_STROKE_WIDTH, SkScalarToFloat(s
troke.getWidth()))); |
260 GR_GL_CALL(gpu->glInterface(), | 259 GR_GL_CALL(gpu->glInterface(), |
261 PathParameterf(pathID, GR_GL_PATH_MITER_LIMIT, SkScalarToFloat(st
roke.getMiter()))); | 260 PathParameterf(pathID, GR_GL_PATH_MITER_LIMIT, SkScalarToFloat(st
roke.getMiter()))); |
262 GrGLenum join = join_to_gl_join(stroke.getJoin()); | 261 GrGLenum join = join_to_gl_join(stroke.getJoin()); |
263 GR_GL_CALL(gpu->glInterface(), PathParameteri(pathID, GR_GL_PATH_JOIN_STYLE,
join)); | 262 GR_GL_CALL(gpu->glInterface(), PathParameteri(pathID, GR_GL_PATH_JOIN_STYLE,
join)); |
264 GrGLenum cap = cap_to_gl_cap(stroke.getCap()); | 263 GrGLenum cap = cap_to_gl_cap(stroke.getCap()); |
265 GR_GL_CALL(gpu->glInterface(), PathParameteri(pathID, GR_GL_PATH_END_CAPS, c
ap)); | 264 GR_GL_CALL(gpu->glInterface(), PathParameteri(pathID, GR_GL_PATH_END_CAPS, c
ap)); |
266 GR_GL_CALL(gpu->glInterface(), PathParameterf(pathID, GR_GL_PATH_STROKE_BOUN
D, 0.02f)); | 265 GR_GL_CALL(gpu->glInterface(), PathParameterf(pathID, GR_GL_PATH_STROKE_BOUN
D, 0.02f)); |
267 } | 266 } |
268 | 267 |
269 void GrGLPath::InitPathObjectEmptyPath(GrGLGpu* gpu, GrGLuint pathID) { | 268 void GrGLPath::InitPathObjectEmptyPath(GrGLGpu* gpu, GrGLuint pathID) { |
270 GR_GL_CALL(gpu->glInterface(), PathCommands(pathID, 0, nullptr, 0, GR_GL_FLO
AT, nullptr)); | 269 GR_GL_CALL(gpu->glInterface(), PathCommands(pathID, 0, nullptr, 0, GR_GL_FLO
AT, nullptr)); |
271 } | 270 } |
272 | 271 |
273 GrGLPath::GrGLPath(GrGLGpu* gpu, const SkPath& origSkPath, const GrStrokeInfo& o
rigStroke) | 272 GrGLPath::GrGLPath(GrGLGpu* gpu, const SkPath& origSkPath, const GrStyle& style) |
274 : INHERITED(gpu, origSkPath, origStroke), | 273 : INHERITED(gpu, origSkPath, style), |
275 fPathID(gpu->glPathRendering()->genPaths(1)) { | 274 fPathID(gpu->glPathRendering()->genPaths(1)) { |
276 | 275 |
277 if (origSkPath.isEmpty()) { | 276 if (origSkPath.isEmpty()) { |
278 InitPathObjectEmptyPath(gpu, fPathID); | 277 InitPathObjectEmptyPath(gpu, fPathID); |
279 fShouldStroke = false; | 278 fShouldStroke = false; |
280 fShouldFill = false; | 279 fShouldFill = false; |
281 } else { | 280 } else { |
282 const SkPath* skPath = &origSkPath; | 281 const SkPath* skPath = &origSkPath; |
283 SkTLazy<SkPath> tmpPath; | 282 SkTLazy<SkPath> tmpPath; |
284 const GrStrokeInfo* stroke = &origStroke; | 283 SkStrokeRec stroke(SkStrokeRec::kFill_InitStyle); |
285 GrStrokeInfo tmpStroke(SkStrokeRec::kFill_InitStyle); | |
286 | 284 |
287 if (stroke->isDashed()) { | 285 if (style.pathEffect()) { |
288 // Skia stroking and NVPR stroking differ with respect to dashing | 286 // Skia stroking and NVPR stroking differ with respect to dashing |
289 // pattern. | 287 // pattern. |
290 // Convert a dashing to either a stroke or a fill. | 288 // Convert a dashing (or other path effect) to either a stroke or a
fill. |
291 if (stroke->applyDashToPath(tmpPath.init(), &tmpStroke, *skPath)) { | 289 if (style.applyPathEffectToPath(tmpPath.init(), &stroke, *skPath, SK
_Scalar1)) { |
292 skPath = tmpPath.get(); | 290 skPath = tmpPath.get(); |
293 stroke = &tmpStroke; | |
294 } | 291 } |
| 292 } else { |
| 293 stroke = style.strokeRec(); |
295 } | 294 } |
296 | 295 |
297 bool didInit = false; | 296 bool didInit = false; |
298 if (stroke->needToApply() && stroke->getCap() != SkPaint::kButt_Cap) { | 297 if (stroke.needToApply() && stroke.getCap() != SkPaint::kButt_Cap) { |
299 // Skia stroking and NVPR stroking differ with respect to stroking | 298 // Skia stroking and NVPR stroking differ with respect to stroking |
300 // end caps of empty subpaths. | 299 // end caps of empty subpaths. |
301 // Convert stroke to fill if path contains empty subpaths. | 300 // Convert stroke to fill if path contains empty subpaths. |
302 didInit = InitPathObjectPathDataCheckingDegenerates(gpu, fPathID, *s
kPath); | 301 didInit = InitPathObjectPathDataCheckingDegenerates(gpu, fPathID, *s
kPath); |
303 if (!didInit) { | 302 if (!didInit) { |
304 if (!tmpPath.isValid()) { | 303 if (!tmpPath.isValid()) { |
305 tmpPath.init(); | 304 tmpPath.init(); |
306 } | 305 } |
307 SkAssertResult(stroke->applyToPath(tmpPath.get(), *skPath)); | 306 SkAssertResult(stroke.applyToPath(tmpPath.get(), *skPath)); |
308 skPath = tmpPath.get(); | 307 skPath = tmpPath.get(); |
309 tmpStroke.setFillStyle(); | 308 stroke.setFillStyle(); |
310 stroke = &tmpStroke; | |
311 } | 309 } |
312 } | 310 } |
313 | 311 |
314 if (!didInit) { | 312 if (!didInit) { |
315 InitPathObjectPathData(gpu, fPathID, *skPath); | 313 InitPathObjectPathData(gpu, fPathID, *skPath); |
316 } | 314 } |
317 | 315 |
318 fShouldStroke = stroke->needToApply(); | 316 fShouldStroke = stroke.needToApply(); |
319 fShouldFill = stroke->isFillStyle() || | 317 fShouldFill = stroke.isFillStyle() || |
320 stroke->getStyle() == SkStrokeRec::kStrokeAndFill_Style; | 318 stroke.getStyle() == SkStrokeRec::kStrokeAndFill_Style; |
321 | 319 |
322 fFillType = convert_skpath_filltype(skPath->getFillType()); | 320 fFillType = convert_skpath_filltype(skPath->getFillType()); |
323 fBounds = skPath->getBounds(); | 321 fBounds = skPath->getBounds(); |
324 | 322 SkScalar radius = stroke.getInflationRadius(); |
| 323 fBounds.outset(radius, radius); |
325 if (fShouldStroke) { | 324 if (fShouldStroke) { |
326 InitPathObjectStroke(gpu, fPathID, *stroke); | 325 InitPathObjectStroke(gpu, fPathID, stroke); |
327 | |
328 // FIXME: try to account for stroking, without rasterizing the strok
e. | |
329 fBounds.outset(stroke->getWidth(), stroke->getWidth()); | |
330 } | 326 } |
331 } | 327 } |
332 | 328 |
333 this->registerWithCache(SkBudgeted::kYes); | 329 this->registerWithCache(SkBudgeted::kYes); |
334 } | 330 } |
335 | 331 |
336 void GrGLPath::onRelease() { | 332 void GrGLPath::onRelease() { |
337 if (0 != fPathID) { | 333 if (0 != fPathID) { |
338 static_cast<GrGLGpu*>(this->getGpu())->glPathRendering()->deletePaths(fP
athID, 1); | 334 static_cast<GrGLGpu*>(this->getGpu())->glPathRendering()->deletePaths(fP
athID, 1); |
339 fPathID = 0; | 335 fPathID = 0; |
340 } | 336 } |
341 | 337 |
342 INHERITED::onRelease(); | 338 INHERITED::onRelease(); |
343 } | 339 } |
344 | 340 |
345 void GrGLPath::onAbandon() { | 341 void GrGLPath::onAbandon() { |
346 fPathID = 0; | 342 fPathID = 0; |
347 | 343 |
348 INHERITED::onAbandon(); | 344 INHERITED::onAbandon(); |
349 } | 345 } |
OLD | NEW |