• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2014 Google Inc.
3  *
4  * Use of this source code is governed by a BSD-style license that can be
5  * found in the LICENSE file.
6  */
7 
8 #include "GrGLPathRange.h"
9 #include "GrGLPath.h"
10 #include "GrGLPathRendering.h"
11 #include "GrGLGpu.h"
12 
GrGLPathRange(GrGLGpu * gpu,PathGenerator * pathGenerator,const GrStyle & style)13 GrGLPathRange::GrGLPathRange(GrGLGpu* gpu, PathGenerator* pathGenerator, const GrStyle& style)
14     : INHERITED(gpu, pathGenerator),
15       fStyle(style),
16       fBasePathID(gpu->glPathRendering()->genPaths(this->getNumPaths())),
17       fGpuMemorySize(0) {
18     this->init();
19     this->registerWithCache(SkBudgeted::kYes);
20 }
21 
GrGLPathRange(GrGLGpu * gpu,GrGLuint basePathID,int numPaths,size_t gpuMemorySize,const GrStyle & style)22 GrGLPathRange::GrGLPathRange(GrGLGpu* gpu,
23                              GrGLuint basePathID,
24                              int numPaths,
25                              size_t gpuMemorySize,
26                              const GrStyle& style)
27     : INHERITED(gpu, numPaths),
28       fStyle(style),
29       fBasePathID(basePathID),
30       fGpuMemorySize(gpuMemorySize) {
31     this->init();
32     this->registerWithCache(SkBudgeted::kYes);
33 }
34 
init()35 void GrGLPathRange::init() {
36     const SkStrokeRec& stroke = fStyle.strokeRec();
37     // Must force fill:
38     // * dashing: NVPR stroke dashing is different to Skia.
39     // * end caps: NVPR stroking degenerate contours with end caps is different to Skia.
40     bool forceFill = fStyle.pathEffect() ||
41             (stroke.needToApply() && stroke.getCap() != SkPaint::kButt_Cap);
42 
43     if (forceFill) {
44         fShouldStroke = false;
45         fShouldFill = true;
46     } else {
47         fShouldStroke = stroke.needToApply();
48         fShouldFill = stroke.isFillStyle() ||
49                 stroke.getStyle() == SkStrokeRec::kStrokeAndFill_Style;
50     }
51 }
52 
onInitPath(int index,const SkPath & origSkPath) const53 void GrGLPathRange::onInitPath(int index, const SkPath& origSkPath) const {
54     GrGLGpu* gpu = static_cast<GrGLGpu*>(this->getGpu());
55     if (nullptr == gpu) {
56         return;
57     }
58     // Make sure the path at this index hasn't been initted already.
59     SkDEBUGCODE(
60         GrGLboolean isPath;
61         GR_GL_CALL_RET(gpu->glInterface(), isPath, IsPath(fBasePathID + index)));
62     SkASSERT(GR_GL_FALSE == isPath);
63 
64     if (origSkPath.isEmpty()) {
65         GrGLPath::InitPathObjectEmptyPath(gpu, fBasePathID + index);
66     } else if (fShouldStroke) {
67         GrGLPath::InitPathObjectPathData(gpu, fBasePathID + index, origSkPath);
68         GrGLPath::InitPathObjectStroke(gpu, fBasePathID + index, fStyle.strokeRec());
69     } else {
70         const SkPath* skPath = &origSkPath;
71         SkTLazy<SkPath> tmpPath;
72         if (!fStyle.isSimpleFill()) {
73             SkStrokeRec::InitStyle fill;
74             // The path effect must be applied to the path. However, if a path effect is present,
75             // we must convert all the paths to fills. The path effect application may leave
76             // simple paths as strokes but converts other paths to fills.
77             // Thus we must stroke the strokes here, so that all paths in the
78             // path range are using the same style.
79             if (!fStyle.applyToPath(tmpPath.init(), &fill, *skPath, SK_Scalar1)) {
80                 return;
81             }
82             // We shouldn't have allowed hairlines or arbitrary path effect styles to get here
83             // so after application we better have a filled path.
84             SkASSERT(SkStrokeRec::kFill_InitStyle == fill);
85             skPath = tmpPath.get();
86 
87         }
88         GrGLPath::InitPathObjectPathData(gpu, fBasePathID + index, *skPath);
89     }
90     // TODO: Use a better approximation for the individual path sizes.
91     fGpuMemorySize += 100;
92 }
93 
onRelease()94 void GrGLPathRange::onRelease() {
95     SkASSERT(this->getGpu());
96 
97     if (0 != fBasePathID) {
98         static_cast<GrGLGpu*>(this->getGpu())->glPathRendering()->deletePaths(fBasePathID,
99                                                                               this->getNumPaths());
100         fBasePathID = 0;
101     }
102 
103     INHERITED::onRelease();
104 }
105 
onAbandon()106 void GrGLPathRange::onAbandon() {
107     fBasePathID = 0;
108 
109     INHERITED::onAbandon();
110 }
111