blob: 34be43b235154d83b3a02dc5f42d79d14bd7f79b [file] [log] [blame]
bsalomon@google.com64aef2b2012-06-11 15:36:13 +00001
2/*
3 * Copyright 2012 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 "GrGLPath.h"
10#include "GrGpuGL.h"
11
12#define GPUGL static_cast<GrGpuGL*>(this->getGpu())
13
14#define GL_CALL(X) GR_GL_CALL(GPUGL->glInterface(), X)
15#define GL_CALL_RET(R, X) GR_GL_CALL_RET(GPUGL->glInterface(), R, X)
16
17namespace {
18inline GrGLubyte verb_to_gl_path_cmd(const SkPath::Verb verb) {
19 static const GrGLubyte gTable[] = {
20 GR_GL_MOVE_TO,
21 GR_GL_LINE_TO,
22 GR_GL_QUADRATIC_CURVE_TO,
23 GR_GL_CUBIC_CURVE_TO,
24 GR_GL_CLOSE_PATH,
25 };
26 GR_STATIC_ASSERT(0 == SkPath::kMove_Verb);
27 GR_STATIC_ASSERT(1 == SkPath::kLine_Verb);
28 GR_STATIC_ASSERT(2 == SkPath::kQuad_Verb);
29 GR_STATIC_ASSERT(3 == SkPath::kCubic_Verb);
30 GR_STATIC_ASSERT(4 == SkPath::kClose_Verb);
31
32 GrAssert(verb >= 0 && verb < GR_ARRAY_COUNT(gTable));
33 return gTable[verb];
34}
35
36inline int num_pts(const SkPath::Verb verb) {
37 static const int gTable[] = {
38 1, // move
39 1, // line
40 2, // quad
41 3, // cubic
42 0, // close
43 };
44 GR_STATIC_ASSERT(0 == SkPath::kMove_Verb);
45 GR_STATIC_ASSERT(1 == SkPath::kLine_Verb);
46 GR_STATIC_ASSERT(2 == SkPath::kQuad_Verb);
47 GR_STATIC_ASSERT(3 == SkPath::kCubic_Verb);
48 GR_STATIC_ASSERT(4 == SkPath::kClose_Verb);
49
50 GrAssert(verb >= 0 && verb < GR_ARRAY_COUNT(gTable));
51 return gTable[verb];
52}
53}
54
55GrGLPath::GrGLPath(GrGpuGL* gpu, const SkPath& path) : INHERITED(gpu) {
56 GL_CALL_RET(fPathID, GenPaths(1));
bsalomon@google.comded4f4b2012-06-28 18:48:06 +000057 //GrPrintf("\tGenPaths ID: %d\n", fPathID);
bsalomon@google.com64aef2b2012-06-11 15:36:13 +000058 SkPath::Iter iter(path, true);
59
60 SkSTArray<16, GrGLubyte, true> pathCommands;
bsalomon@google.comb51c6332012-06-11 15:46:05 +000061#ifndef SK_SCALAR_IS_FLOAT
bsalomon@google.comd1e533f2012-06-28 18:56:22 +000062 GrCrash("Assumes scalar is float.");
bsalomon@google.comb51c6332012-06-11 15:46:05 +000063#endif
bsalomon@google.com64aef2b2012-06-11 15:36:13 +000064 SkSTArray<16, SkPoint, true> pathPoints;
65
66 int verbCnt = path.countVerbs();
67 int pointCnt = path.countPoints();
68 pathCommands.resize_back(verbCnt);
69 pathPoints.resize_back(pointCnt);
70
71 // TODO: Direct access to path points since we could pass them on directly.
72 path.getPoints(&pathPoints[0], pointCnt);
73 path.getVerbs(&pathCommands[0], verbCnt);
74
75 GR_DEBUGCODE(int numPts = 0);
76 for (int i = 0; i < verbCnt; ++i) {
77 SkPath::Verb v = static_cast<SkPath::Verb>(pathCommands[i]);
78 pathCommands[i] = verb_to_gl_path_cmd(v);
79 GR_DEBUGCODE(numPts += num_pts(v));
80 }
81 GrAssert(pathPoints.count() == numPts);
82
83 GL_CALL(PathCommands(fPathID,
84 verbCnt, &pathCommands[0],
85 2 * pointCnt, GR_GL_FLOAT, &pathPoints[0]));
bsalomon@google.comded4f4b2012-06-28 18:48:06 +000086 //GrPrintf("\tPathCommands ID: %d\n", fPathID);
87 fBounds = path.getBounds();
bsalomon@google.com64aef2b2012-06-11 15:36:13 +000088}
89
90GrGLPath::~GrGLPath() {
91 this->release();
92}
93
94void GrGLPath::onRelease() {
95 if (0 != fPathID) {
bsalomon@google.comded4f4b2012-06-28 18:48:06 +000096 // FIXME: When we draw a clipped path we may get a call sequence that looks
97 // like this:
98 // GenPaths(1, &fPathID); // fPathID = 1, the path to draw
99 // PathCommands(1, ...);
100 // GenPaths(1, &fPathID); // fPathID = 2, the clip path
101 // PathCommands(2, ...);
102 // PathStencilFunc(...);
103 // StencilFillPath(2, ...); // draw the clip
104 // DeletePath(1, &fPathID); // fPathID == 2
105 // PathStencilFunc(...);
106 // StencilFillPath(2, ...); // draw the path
107 // DeletePath(1, &fPathID); // fPathID == 1
108 //
109 // Deleting the clip path causes the second StencilFillPath to fail with
110 // INVALID_OPERATION.
111#if 0
bsalomon@google.com64aef2b2012-06-11 15:36:13 +0000112 GL_CALL(DeletePaths(1, fPathID));
bsalomon@google.comded4f4b2012-06-28 18:48:06 +0000113 //GrPrintf("\tDeletePaths ID: %d\n", fPathID);
114#else
115 //GrPrintf("\tLeak Path ID: %d\n", fPathID);
116#endif
bsalomon@google.com64aef2b2012-06-11 15:36:13 +0000117 fPathID = 0;
118 }
119}
120
121void GrGLPath::onAbandon() {
122 fPathID = 0;
123}
124