1 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 17 namespace { 18 inline 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 && (size_t)verb < GR_ARRAY_COUNT(gTable)); 33 return gTable[verb]; 34 } 35 36 #ifdef SK_DEBUG 37 inline int num_pts(const SkPath::Verb verb) { 38 static const int gTable[] = { 39 1, // move 40 1, // line 41 2, // quad 42 3, // cubic 43 0, // close 44 }; 45 GR_STATIC_ASSERT(0 == SkPath::kMove_Verb); 46 GR_STATIC_ASSERT(1 == SkPath::kLine_Verb); 47 GR_STATIC_ASSERT(2 == SkPath::kQuad_Verb); 48 GR_STATIC_ASSERT(3 == SkPath::kCubic_Verb); 49 GR_STATIC_ASSERT(4 == SkPath::kClose_Verb); 50 51 GrAssert(verb >= 0 && (size_t)verb < GR_ARRAY_COUNT(gTable)); 52 return gTable[verb]; 53 } 54 #endif 55 } 56 57 static const bool kIsWrapped = false; // The constructor creates the GL path object. 58 59 GrGLPath::GrGLPath(GrGpuGL* gpu, const SkPath& path) : INHERITED(gpu, kIsWrapped) { 60 GL_CALL_RET(fPathID, GenPaths(1)); 61 SkPath::Iter iter(path, true); 62 63 SkSTArray<16, GrGLubyte, true> pathCommands; 64 #ifndef SK_SCALAR_IS_FLOAT 65 GrCrash("Assumes scalar is float."); 66 #endif 67 SkSTArray<16, SkPoint, true> pathPoints; 68 69 int verbCnt = path.countVerbs(); 70 int pointCnt = path.countPoints(); 71 pathCommands.resize_back(verbCnt); 72 pathPoints.resize_back(pointCnt); 73 74 // TODO: Direct access to path points since we could pass them on directly. 75 path.getPoints(&pathPoints[0], pointCnt); 76 path.getVerbs(&pathCommands[0], verbCnt); 77 78 GR_DEBUGCODE(int numPts = 0); 79 for (int i = 0; i < verbCnt; ++i) { 80 SkPath::Verb v = static_cast<SkPath::Verb>(pathCommands[i]); 81 pathCommands[i] = verb_to_gl_path_cmd(v); 82 GR_DEBUGCODE(numPts += num_pts(v)); 83 } 84 GrAssert(pathPoints.count() == numPts); 85 86 GL_CALL(PathCommands(fPathID, 87 verbCnt, &pathCommands[0], 88 2 * pointCnt, GR_GL_FLOAT, &pathPoints[0])); 89 fBounds = path.getBounds(); 90 } 91 92 GrGLPath::~GrGLPath() { 93 this->release(); 94 } 95 96 void GrGLPath::onRelease() { 97 if (0 != fPathID && !this->isWrapped()) { 98 GL_CALL(DeletePaths(fPathID, 1)); 99 fPathID = 0; 100 } 101 102 INHERITED::onRelease(); 103 } 104 105 void GrGLPath::onAbandon() { 106 fPathID = 0; 107 108 INHERITED::onAbandon(); 109 } 110