1096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger/* 2096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger * Copyright 2013 Google Inc. 3096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger * 4096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger * Use of this source code is governed by a BSD-style license that can be 5096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger * found in the LICENSE file. 6096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger */ 7096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger 8096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger#include "gl/GrGLExtensions.h" 9096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger#include "gl/GrGLDefines.h" 10096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger#include "gl/GrGLUtil.h" 11096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger 12096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger#include "SkTSearch.h" 13096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger#include "SkTSort.h" 14096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger 15096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenbergernamespace { 167839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergerinline bool extension_compare(const SkString& a, const SkString& b) { 177839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger return strcmp(a.c_str(), b.c_str()) < 0; 18096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger} 19096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger} 20096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger 21096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenbergerbool GrGLExtensions::init(GrGLBinding binding, 22096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger GrGLGetStringProc getString, 23096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger GrGLGetStringiProc getStringi, 24096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger GrGLGetIntegervProc getIntegerv) { 25096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger fStrings.reset(); 26096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger if (NULL == getString) { 27096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger return false; 28096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger } 290a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger 300a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger // glGetStringi and indexed extensions were added in version 3.0 of desktop GL and ES. 310a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger const GrGLubyte* verString = getString(GR_GL_VERSION); 320a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger if (NULL == verString) { 330a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger return false; 34096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger } 350a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger GrGLVersion version = GrGLGetVersionFromString((const char*) verString); 360a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger bool indexed = version >= GR_GL_VER(3, 0); 370a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger 38096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger if (indexed) { 39096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger if (NULL == getStringi || NULL == getIntegerv) { 40096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger return false; 41096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger } 42096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger GrGLint extensionCnt = 0; 43096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger getIntegerv(GR_GL_NUM_EXTENSIONS, &extensionCnt); 44096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger fStrings.push_back_n(extensionCnt); 45096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger for (int i = 0; i < extensionCnt; ++i) { 46096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger const char* ext = (const char*) getStringi(GR_GL_EXTENSIONS, i); 47096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger fStrings[i] = ext; 48096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger } 49096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger } else { 50096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger const char* extensions = (const char*) getString(GR_GL_EXTENSIONS); 51096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger if (NULL == extensions) { 52096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger return false; 53096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger } 54096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger while (true) { 55096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger // skip over multiple spaces between extensions 56096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger while (' ' == *extensions) { 57096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger ++extensions; 58096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger } 59096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger // quit once we reach the end of the string. 60096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger if ('\0' == *extensions) { 61096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger break; 62096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger } 63096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger // we found an extension 64096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger size_t length = strcspn(extensions, " "); 65096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger fStrings.push_back().set(extensions, length); 66096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger extensions += length; 67096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger } 68096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger } 6958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger if (!fStrings.empty()) { 707839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger SkTLessFunctionToFunctorAdaptor<SkString, extension_compare> cmp; 71096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger SkTQSort(&fStrings.front(), &fStrings.back(), cmp); 72096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger } 73096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger return true; 74096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger} 75096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger 76096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenbergerbool GrGLExtensions::has(const char* ext) const { 7758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger if (fStrings.empty()) { 7858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger return false; 7958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger } 80096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger SkString extensionStr(ext); 81096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger int idx = SkTSearch<SkString, extension_compare>(&fStrings.front(), 82096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger fStrings.count(), 83096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger extensionStr, 84096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger sizeof(SkString)); 85096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger return idx >= 0; 86096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger} 877839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 887839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergervoid GrGLExtensions::print(const char* sep) const { 897839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger if (NULL == sep) { 907839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger sep = " "; 917839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger } 927839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger int cnt = fStrings.count(); 937839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger for (int i = 0; i < cnt; ++i) { 947839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger GrPrintf("%s%s", fStrings[i].c_str(), (i < cnt - 1) ? sep : ""); 957839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger } 967839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger} 97