blob: 6ed7bcc425dfdc89b499a050ed245f9e4fa5fa69 [file] [log] [blame]
cdaltonb85a0aa2014-07-21 15:32:44 -07001/*
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"
cdaltonc7103a12014-08-11 14:05:05 -070010#include "GrGLPathRendering.h"
jvanverth39edf762014-12-22 11:44:19 -080011#include "GrGLGpu.h"
cdaltonb85a0aa2014-07-21 15:32:44 -070012
kkinnunen50b58e62015-05-18 23:02:07 -070013GrGLPathRange::GrGLPathRange(GrGLGpu* gpu, PathGenerator* pathGenerator, const GrStrokeInfo& stroke)
14 : INHERITED(gpu, pathGenerator),
15 fStroke(stroke),
cdalton855d83f2014-09-18 13:51:53 -070016 fBasePathID(gpu->glPathRendering()->genPaths(this->getNumPaths())),
17 fGpuMemorySize(0) {
kkinnunen50b58e62015-05-18 23:02:07 -070018 this->init();
kkinnunen2e6055b2016-04-22 01:48:29 -070019 this->registerWithCache(SkBudgeted::kYes);
cdalton855d83f2014-09-18 13:51:53 -070020}
21
bsalomon861e1032014-12-16 07:33:49 -080022GrGLPathRange::GrGLPathRange(GrGLGpu* gpu,
cdalton855d83f2014-09-18 13:51:53 -070023 GrGLuint basePathID,
24 int numPaths,
25 size_t gpuMemorySize,
kkinnunen50b58e62015-05-18 23:02:07 -070026 const GrStrokeInfo& stroke)
27 : INHERITED(gpu, numPaths),
28 fStroke(stroke),
cdalton855d83f2014-09-18 13:51:53 -070029 fBasePathID(basePathID),
30 fGpuMemorySize(gpuMemorySize) {
kkinnunen50b58e62015-05-18 23:02:07 -070031 this->init();
kkinnunen2e6055b2016-04-22 01:48:29 -070032 this->registerWithCache(SkBudgeted::kYes);
cdaltonb85a0aa2014-07-21 15:32:44 -070033}
34
kkinnunen50b58e62015-05-18 23:02:07 -070035void GrGLPathRange::init() {
kkinnunen1e2913e2015-12-01 04:35:37 -080036 // Must force fill:
37 // * dashing: NVPR stroke dashing is different to Skia.
38 // * end caps: NVPR stroking degenerate contours with end caps is different to Skia.
39 bool forceFill = fStroke.isDashed() ||
40 (fStroke.needToApply() && fStroke.getCap() != SkPaint::kButt_Cap);
41
42 if (forceFill) {
kkinnunen50b58e62015-05-18 23:02:07 -070043 fShouldStroke = false;
44 fShouldFill = true;
45 } else {
46 fShouldStroke = fStroke.needToApply();
47 fShouldFill = fStroke.isFillStyle() ||
48 fStroke.getStyle() == SkStrokeRec::kStrokeAndFill_Style;
49 }
50}
51
52void GrGLPathRange::onInitPath(int index, const SkPath& origSkPath) const {
bsalomon861e1032014-12-16 07:33:49 -080053 GrGLGpu* gpu = static_cast<GrGLGpu*>(this->getGpu());
halcanary96fcdcc2015-08-27 07:41:13 -070054 if (nullptr == gpu) {
cdaltonb85a0aa2014-07-21 15:32:44 -070055 return;
56 }
57
cdaltonb85a0aa2014-07-21 15:32:44 -070058 // Make sure the path at this index hasn't been initted already.
kkinnunen5b653572014-08-20 04:13:27 -070059 SkDEBUGCODE(
60 GrGLboolean isPath;
61 GR_GL_CALL_RET(gpu->glInterface(), isPath, IsPath(fBasePathID + index)));
62 SkASSERT(GR_GL_FALSE == isPath);
cdaltonb85a0aa2014-07-21 15:32:44 -070063
kkinnunen1e2913e2015-12-01 04:35:37 -080064 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, fStroke);
69 } else {
70 const SkPath* skPath = &origSkPath;
71 SkTLazy<SkPath> tmpPath;
72 const GrStrokeInfo* stroke = &fStroke;
73 GrStrokeInfo tmpStroke(SkStrokeRec::kFill_InitStyle);
kkinnunen50b58e62015-05-18 23:02:07 -070074
kkinnunen1e2913e2015-12-01 04:35:37 -080075 // Dashing must be applied to the path. However, if dashing is present,
76 // we must convert all the paths to fills. The GrStrokeInfo::applyDash leaves
77 // simple paths as strokes but converts other paths to fills.
78 // Thus we must stroke the strokes here, so that all paths in the
79 // path range are using the same style.
80 if (fStroke.isDashed()) {
81 if (!stroke->applyDashToPath(tmpPath.init(), &tmpStroke, *skPath)) {
kkinnunen50b58e62015-05-18 23:02:07 -070082 return;
83 }
kkinnunen1e2913e2015-12-01 04:35:37 -080084 skPath = tmpPath.get();
85 stroke = &tmpStroke;
kkinnunen50b58e62015-05-18 23:02:07 -070086 }
kkinnunen1e2913e2015-12-01 04:35:37 -080087 if (stroke->needToApply()) {
88 if (!tmpPath.isValid()) {
89 tmpPath.init();
90 }
91 if (!stroke->applyToPath(tmpPath.get(), *tmpPath.get())) {
92 return;
93 }
94 }
95 GrGLPath::InitPathObjectPathData(gpu, fBasePathID + index, *skPath);
kkinnunen50b58e62015-05-18 23:02:07 -070096 }
cdalton855d83f2014-09-18 13:51:53 -070097 // TODO: Use a better approximation for the individual path sizes.
98 fGpuMemorySize += 100;
cdaltonb85a0aa2014-07-21 15:32:44 -070099}
100
101void GrGLPathRange::onRelease() {
bsalomon49f085d2014-09-05 13:34:00 -0700102 SkASSERT(this->getGpu());
cdaltonb85a0aa2014-07-21 15:32:44 -0700103
kkinnunen2e6055b2016-04-22 01:48:29 -0700104 if (0 != fBasePathID) {
bsalomon861e1032014-12-16 07:33:49 -0800105 static_cast<GrGLGpu*>(this->getGpu())->glPathRendering()->deletePaths(fBasePathID,
cdalton855d83f2014-09-18 13:51:53 -0700106 this->getNumPaths());
cdaltonb85a0aa2014-07-21 15:32:44 -0700107 fBasePathID = 0;
108 }
109
110 INHERITED::onRelease();
111}
112
113void GrGLPathRange::onAbandon() {
114 fBasePathID = 0;
115
116 INHERITED::onAbandon();
117}