blob: 4714b924ab4d94e3ad41ae4f86d4d38c6637209e [file] [log] [blame]
cdaltonb85a0aa2014-07-21 15:32:44 -07001
2/*
3 * Copyright 2014 Google Inc.
4 *
5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file.
7 */
8
9#include "GrGLPathRange.h"
10#include "GrGLPath.h"
cdaltonc7103a12014-08-11 14:05:05 -070011#include "GrGLPathRendering.h"
jvanverth39edf762014-12-22 11:44:19 -080012#include "GrGLGpu.h"
cdaltonb85a0aa2014-07-21 15:32:44 -070013
kkinnunen50b58e62015-05-18 23:02:07 -070014GrGLPathRange::GrGLPathRange(GrGLGpu* gpu, PathGenerator* pathGenerator, const GrStrokeInfo& stroke)
15 : INHERITED(gpu, pathGenerator),
16 fStroke(stroke),
cdalton855d83f2014-09-18 13:51:53 -070017 fBasePathID(gpu->glPathRendering()->genPaths(this->getNumPaths())),
18 fGpuMemorySize(0) {
kkinnunen50b58e62015-05-18 23:02:07 -070019 this->init();
cdalton855d83f2014-09-18 13:51:53 -070020 this->registerWithCache();
21}
22
bsalomon861e1032014-12-16 07:33:49 -080023GrGLPathRange::GrGLPathRange(GrGLGpu* gpu,
cdalton855d83f2014-09-18 13:51:53 -070024 GrGLuint basePathID,
25 int numPaths,
26 size_t gpuMemorySize,
kkinnunen50b58e62015-05-18 23:02:07 -070027 const GrStrokeInfo& stroke)
28 : INHERITED(gpu, numPaths),
29 fStroke(stroke),
cdalton855d83f2014-09-18 13:51:53 -070030 fBasePathID(basePathID),
31 fGpuMemorySize(gpuMemorySize) {
kkinnunen50b58e62015-05-18 23:02:07 -070032 this->init();
cdalton855d83f2014-09-18 13:51:53 -070033 this->registerWithCache();
cdaltonb85a0aa2014-07-21 15:32:44 -070034}
35
kkinnunen50b58e62015-05-18 23:02:07 -070036void GrGLPathRange::init() {
kkinnunen1e2913e2015-12-01 04:35:37 -080037 // 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 = fStroke.isDashed() ||
41 (fStroke.needToApply() && fStroke.getCap() != SkPaint::kButt_Cap);
42
43 if (forceFill) {
kkinnunen50b58e62015-05-18 23:02:07 -070044 fShouldStroke = false;
45 fShouldFill = true;
46 } else {
47 fShouldStroke = fStroke.needToApply();
48 fShouldFill = fStroke.isFillStyle() ||
49 fStroke.getStyle() == SkStrokeRec::kStrokeAndFill_Style;
50 }
51}
52
53void GrGLPathRange::onInitPath(int index, const SkPath& origSkPath) const {
bsalomon861e1032014-12-16 07:33:49 -080054 GrGLGpu* gpu = static_cast<GrGLGpu*>(this->getGpu());
halcanary96fcdcc2015-08-27 07:41:13 -070055 if (nullptr == gpu) {
cdaltonb85a0aa2014-07-21 15:32:44 -070056 return;
57 }
58
cdaltonb85a0aa2014-07-21 15:32:44 -070059 // Make sure the path at this index hasn't been initted already.
kkinnunen5b653572014-08-20 04:13:27 -070060 SkDEBUGCODE(
61 GrGLboolean isPath;
62 GR_GL_CALL_RET(gpu->glInterface(), isPath, IsPath(fBasePathID + index)));
63 SkASSERT(GR_GL_FALSE == isPath);
cdaltonb85a0aa2014-07-21 15:32:44 -070064
kkinnunen1e2913e2015-12-01 04:35:37 -080065 if (origSkPath.isEmpty()) {
66 GrGLPath::InitPathObjectEmptyPath(gpu, fBasePathID + index);
67 } else if (fShouldStroke) {
68 GrGLPath::InitPathObjectPathData(gpu, fBasePathID + index, origSkPath);
69 GrGLPath::InitPathObjectStroke(gpu, fBasePathID + index, fStroke);
70 } else {
71 const SkPath* skPath = &origSkPath;
72 SkTLazy<SkPath> tmpPath;
73 const GrStrokeInfo* stroke = &fStroke;
74 GrStrokeInfo tmpStroke(SkStrokeRec::kFill_InitStyle);
kkinnunen50b58e62015-05-18 23:02:07 -070075
kkinnunen1e2913e2015-12-01 04:35:37 -080076 // Dashing must be applied to the path. However, if dashing is present,
77 // we must convert all the paths to fills. The GrStrokeInfo::applyDash leaves
78 // simple paths as strokes but converts other paths to fills.
79 // Thus we must stroke the strokes here, so that all paths in the
80 // path range are using the same style.
81 if (fStroke.isDashed()) {
82 if (!stroke->applyDashToPath(tmpPath.init(), &tmpStroke, *skPath)) {
kkinnunen50b58e62015-05-18 23:02:07 -070083 return;
84 }
kkinnunen1e2913e2015-12-01 04:35:37 -080085 skPath = tmpPath.get();
86 stroke = &tmpStroke;
kkinnunen50b58e62015-05-18 23:02:07 -070087 }
kkinnunen1e2913e2015-12-01 04:35:37 -080088 if (stroke->needToApply()) {
89 if (!tmpPath.isValid()) {
90 tmpPath.init();
91 }
92 if (!stroke->applyToPath(tmpPath.get(), *tmpPath.get())) {
93 return;
94 }
95 }
96 GrGLPath::InitPathObjectPathData(gpu, fBasePathID + index, *skPath);
kkinnunen50b58e62015-05-18 23:02:07 -070097 }
cdalton855d83f2014-09-18 13:51:53 -070098 // TODO: Use a better approximation for the individual path sizes.
99 fGpuMemorySize += 100;
cdaltonb85a0aa2014-07-21 15:32:44 -0700100}
101
102void GrGLPathRange::onRelease() {
bsalomon49f085d2014-09-05 13:34:00 -0700103 SkASSERT(this->getGpu());
cdaltonb85a0aa2014-07-21 15:32:44 -0700104
bsalomon6dc6f5f2015-06-18 09:12:16 -0700105 if (0 != fBasePathID && this->shouldFreeResources()) {
bsalomon861e1032014-12-16 07:33:49 -0800106 static_cast<GrGLGpu*>(this->getGpu())->glPathRendering()->deletePaths(fBasePathID,
cdalton855d83f2014-09-18 13:51:53 -0700107 this->getNumPaths());
cdaltonb85a0aa2014-07-21 15:32:44 -0700108 fBasePathID = 0;
109 }
110
111 INHERITED::onRelease();
112}
113
114void GrGLPathRange::onAbandon() {
115 fBasePathID = 0;
116
117 INHERITED::onAbandon();
118}