15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Copyright 2012 Google Inc. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Use of this source code is governed by a BSD-style license that can be 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * found in the LICENSE file. 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 85d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 95d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "GrGLPath.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "GrGLPathRendering.h" 115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "GrGpuGL.h" 1290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace { 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)inline GrGLubyte verb_to_gl_path_cmd(SkPath::Verb verb) { 15a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) static const GrGLubyte gTable[] = { 162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GR_GL_MOVE_TO, 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GR_GL_LINE_TO, 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GR_GL_QUADRATIC_CURVE_TO, 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 0xFF, // conic 20c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) GR_GL_CUBIC_CURVE_TO, 21c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) GR_GL_CLOSE_PATH, 22c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) }; 23c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) GR_STATIC_ASSERT(0 == SkPath::kMove_Verb); 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GR_STATIC_ASSERT(1 == SkPath::kLine_Verb); 256e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) GR_STATIC_ASSERT(2 == SkPath::kQuad_Verb); 2690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) GR_STATIC_ASSERT(4 == SkPath::kCubic_Verb); 275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) GR_STATIC_ASSERT(5 == SkPath::kClose_Verb); 286e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) SkASSERT(verb >= 0 && (size_t)verb < SK_ARRAY_COUNT(gTable)); 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return gTable[verb]; 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef SK_DEBUG 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)inline int num_pts(SkPath::Verb verb) { 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const int gTable[] = { 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1, // move 37a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 1, // line 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2, // quad 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2, // conic 40c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 3, // cubic 41c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 0, // close 42c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) }; 43a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) GR_STATIC_ASSERT(0 == SkPath::kMove_Verb); 44c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) GR_STATIC_ASSERT(1 == SkPath::kLine_Verb); 45c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) GR_STATIC_ASSERT(2 == SkPath::kQuad_Verb); 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GR_STATIC_ASSERT(4 == SkPath::kCubic_Verb); 47c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) GR_STATIC_ASSERT(5 == SkPath::kClose_Verb); 48c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 49a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) SkASSERT(verb >= 0 && (size_t)verb < SK_ARRAY_COUNT(gTable)); 50c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return gTable[verb]; 51c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 53f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 54f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)inline GrGLenum join_to_gl_join(SkPaint::Join join) { 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static GrGLenum gSkJoinsToGrGLJoins[] = { 56f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) GR_GL_MITER_REVERT, 57f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) GR_GL_ROUND, 58f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) GR_GL_BEVEL 591e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) }; 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return gSkJoinsToGrGLJoins[join]; 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GR_STATIC_ASSERT(0 == SkPaint::kMiter_Join); 62a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) GR_STATIC_ASSERT(1 == SkPaint::kRound_Join); 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GR_STATIC_ASSERT(2 == SkPaint::kBevel_Join); 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GR_STATIC_ASSERT(SK_ARRAY_COUNT(gSkJoinsToGrGLJoins) == SkPaint::kJoinCount); 655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 676e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)inline GrGLenum cap_to_gl_cap(SkPaint::Cap cap) { 68f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) static GrGLenum gSkCapsToGrGLCaps[] = { 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GR_GL_FLAT, 702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GR_GL_ROUND, 7190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) GR_GL_SQUARE 72f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) }; 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return gSkCapsToGrGLCaps[cap]; 74a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) GR_STATIC_ASSERT(0 == SkPaint::kButt_Cap); 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GR_STATIC_ASSERT(1 == SkPaint::kRound_Cap); 762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GR_STATIC_ASSERT(2 == SkPaint::kSquare_Cap); 772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GR_STATIC_ASSERT(SK_ARRAY_COUNT(gSkCapsToGrGLCaps) == SkPaint::kCapCount); 78558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch} 79f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 82010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)static const bool kIsWrapped = false; // The constructor creates the GL path object. 83f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 84f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)void GrGLPath::InitPathObject(GrGpuGL* gpu, 856e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) GrGLuint pathID, 866e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) const SkPath& skPath, 876e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) const SkStrokeRec& stroke) { 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!skPath.isEmpty()) { 897dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch SkSTArray<16, GrGLubyte, true> pathCommands; 907dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch SkSTArray<16, SkPoint, true> pathPoints; 917dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 927dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch int verbCnt = skPath.countVerbs(); 937dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch int pointCnt = skPath.countPoints(); 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pathCommands.resize_back(verbCnt); 95a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) pathPoints.resize_back(pointCnt); 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO: Direct access to path points since we could pass them on directly. 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) skPath.getPoints(&pathPoints[0], pointCnt); 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) skPath.getVerbs(&pathCommands[0], verbCnt); 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SkDEBUGCODE(int numPts = 0); 10290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) for (int i = 0; i < verbCnt; ++i) { 10390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) SkPath::Verb v = static_cast<SkPath::Verb>(pathCommands[i]); 1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) pathCommands[i] = verb_to_gl_path_cmd(v); 1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SkDEBUGCODE(numPts += num_pts(v)); 1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SkASSERT(pathPoints.count() == numPts); 1085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GR_GL_CALL(gpu->glInterface(), 110f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) PathCommands(pathID, verbCnt, &pathCommands[0], 111f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 2 * pointCnt, GR_GL_FLOAT, &pathPoints[0])); 112a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } else { 113558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch GR_GL_CALL(gpu->glInterface(), PathCommands(pathID, 0, NULL, 0, GR_GL_FLOAT, NULL)); 114f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 1155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 11690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (stroke.needToApply()) { 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SkASSERT(!stroke.isHairlineStyle()); 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GR_GL_CALL(gpu->glInterface(), 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PathParameterf(pathID, GR_GL_PATH_STROKE_WIDTH, SkScalarToFloat(stroke.getWidth()))); 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GR_GL_CALL(gpu->glInterface(), 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PathParameterf(pathID, GR_GL_PATH_MITER_LIMIT, SkScalarToFloat(stroke.getMiter()))); 122 GrGLenum join = join_to_gl_join(stroke.getJoin()); 123 GR_GL_CALL(gpu->glInterface(), 124 PathParameteri(pathID, GR_GL_PATH_JOIN_STYLE, join)); 125 GrGLenum cap = cap_to_gl_cap(stroke.getCap()); 126 GR_GL_CALL(gpu->glInterface(), 127 PathParameteri(pathID, GR_GL_PATH_INITIAL_END_CAP, cap)); 128 GR_GL_CALL(gpu->glInterface(), 129 PathParameteri(pathID, GR_GL_PATH_TERMINAL_END_CAP, cap)); 130 } 131} 132 133GrGLPath::GrGLPath(GrGpuGL* gpu, const SkPath& path, const SkStrokeRec& stroke) 134 : INHERITED(gpu, kIsWrapped, path, stroke), 135 fPathID(gpu->glPathRendering()->genPaths(1)) { 136 137 InitPathObject(gpu, fPathID, fSkPath, stroke); 138 139 if (stroke.needToApply()) { 140 // FIXME: try to account for stroking, without rasterizing the stroke. 141 fBounds.outset(stroke.getWidth(), stroke.getWidth()); 142 } 143 this->registerWithCache(); 144} 145 146GrGLPath::~GrGLPath() { 147 this->release(); 148} 149 150void GrGLPath::onRelease() { 151 if (0 != fPathID && !this->isWrapped()) { 152 static_cast<GrGpuGL*>(this->getGpu())->glPathRendering()->deletePaths(fPathID, 1); 153 fPathID = 0; 154 } 155 156 INHERITED::onRelease(); 157} 158 159void GrGLPath::onAbandon() { 160 fPathID = 0; 161 162 INHERITED::onAbandon(); 163} 164