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