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