| 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 |