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 |