1 /* 2 * Copyright 2013 Google Inc. 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8 #include "gl/GrGLExtensions.h" 9 #include "gl/GrGLDefines.h" 10 #include "gl/GrGLUtil.h" 11 12 #include "SkTSearch.h" 13 #include "SkTSort.h" 14 15 namespace { 16 inline bool extension_compare(const SkString& a, const SkString& b) { 17 return strcmp(a.c_str(), b.c_str()) < 0; 18 } 19 } 20 21 bool GrGLExtensions::init(GrGLBinding binding, 22 GrGLGetStringProc getString, 23 GrGLGetStringiProc getStringi, 24 GrGLGetIntegervProc getIntegerv) { 25 fStrings.reset(); 26 if (NULL == getString) { 27 return false; 28 } 29 30 // glGetStringi and indexed extensions were added in version 3.0 of desktop GL and ES. 31 const GrGLubyte* verString = getString(GR_GL_VERSION); 32 if (NULL == verString) { 33 return false; 34 } 35 GrGLVersion version = GrGLGetVersionFromString((const char*) verString); 36 bool indexed = version >= GR_GL_VER(3, 0); 37 38 if (indexed) { 39 if (NULL == getStringi || NULL == getIntegerv) { 40 return false; 41 } 42 GrGLint extensionCnt = 0; 43 getIntegerv(GR_GL_NUM_EXTENSIONS, &extensionCnt); 44 fStrings.push_back_n(extensionCnt); 45 for (int i = 0; i < extensionCnt; ++i) { 46 const char* ext = (const char*) getStringi(GR_GL_EXTENSIONS, i); 47 fStrings[i] = ext; 48 } 49 } else { 50 const char* extensions = (const char*) getString(GR_GL_EXTENSIONS); 51 if (NULL == extensions) { 52 return false; 53 } 54 while (true) { 55 // skip over multiple spaces between extensions 56 while (' ' == *extensions) { 57 ++extensions; 58 } 59 // quit once we reach the end of the string. 60 if ('\0' == *extensions) { 61 break; 62 } 63 // we found an extension 64 size_t length = strcspn(extensions, " "); 65 fStrings.push_back().set(extensions, length); 66 extensions += length; 67 } 68 } 69 if (!fStrings.empty()) { 70 SkTLessFunctionToFunctorAdaptor<SkString, extension_compare> cmp; 71 SkTQSort(&fStrings.front(), &fStrings.back(), cmp); 72 } 73 return true; 74 } 75 76 bool GrGLExtensions::has(const char* ext) const { 77 if (fStrings.empty()) { 78 return false; 79 } 80 SkString extensionStr(ext); 81 int idx = SkTSearch<SkString, extension_compare>(&fStrings.front(), 82 fStrings.count(), 83 extensionStr, 84 sizeof(SkString)); 85 return idx >= 0; 86 } 87 88 void GrGLExtensions::print(const char* sep) const { 89 if (NULL == sep) { 90 sep = " "; 91 } 92 int cnt = fStrings.count(); 93 for (int i = 0; i < cnt; ++i) { 94 GrPrintf("%s%s", fStrings[i].c_str(), (i < cnt - 1) ? sep : ""); 95 } 96 } 97